about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--BUGS16
-rw-r--r--ChangeLog218
-rw-r--r--FAQ18
-rw-r--r--Makerules4
-rw-r--r--NEWS30
-rw-r--r--aclocal.m41
-rwxr-xr-xconfigure136
-rw-r--r--configure.in2
-rw-r--r--csu/Makefile6
-rw-r--r--db2/Makefile2
-rw-r--r--db2/btree/bt_close.c4
-rw-r--r--db2/btree/bt_conv.c22
-rw-r--r--db2/btree/bt_cursor.c76
-rw-r--r--db2/btree/bt_put.c4
-rw-r--r--db2/btree/bt_rec.c13
-rw-r--r--db2/btree/bt_recno.c38
-rw-r--r--db2/btree/btree.src8
-rw-r--r--db2/btree/btree_auto.c14
-rw-r--r--db2/clib/getlong.c1
-rw-r--r--db2/db.h16
-rw-r--r--db2/db/db.c73
-rw-r--r--db2/db/db_auto.c16
-rw-r--r--db2/db/db_conv.c68
-rw-r--r--db2/db/db_pr.c63
-rw-r--r--db2/db/db_ret.c9
-rw-r--r--db2/db/db_thread.c10
-rw-r--r--db2/db_185.h10
-rw-r--r--db2/db_int.h22
-rw-r--r--db2/hash/hash.c90
-rw-r--r--db2/hash/hash_auto.c14
-rw-r--r--db2/hash/hash_conv.c22
-rw-r--r--db2/hash/hash_dup.c49
-rw-r--r--db2/hash/hash_func.c6
-rw-r--r--db2/hash/hash_page.c69
-rw-r--r--db2/hash/hash_rec.c12
-rw-r--r--db2/include/btree.h8
-rw-r--r--db2/include/btree_ext.h2
-rw-r--r--db2/include/db.h.src17
-rw-r--r--db2/include/db_185.h.src10
-rw-r--r--db2/include/db_cxx.h10
-rw-r--r--db2/include/db_ext.h4
-rw-r--r--db2/include/db_int.h.src14
-rw-r--r--db2/include/db_page.h32
-rw-r--r--db2/include/db_shash.h22
-rw-r--r--db2/include/hash_ext.h3
-rw-r--r--db2/include/lock.h8
-rw-r--r--db2/include/log.h10
-rw-r--r--db2/include/log_ext.h6
-rw-r--r--db2/include/mp.h6
-rw-r--r--db2/include/shqueue.h37
-rw-r--r--db2/include/txn.h27
-rw-r--r--db2/lock/lock.c40
-rw-r--r--db2/lock/lock_deadlock.c9
-rw-r--r--db2/log/log.c104
-rw-r--r--db2/log/log_archive.c76
-rw-r--r--db2/log/log_auto.c4
-rw-r--r--db2/log/log_get.c9
-rw-r--r--db2/log/log_put.c23
-rw-r--r--db2/log/log_register.c11
-rw-r--r--db2/mp/mp_bh.c32
-rw-r--r--db2/mp/mp_fget.c10
-rw-r--r--db2/mp/mp_fopen.c78
-rw-r--r--db2/mp/mp_fput.c8
-rw-r--r--db2/mp/mp_fset.c4
-rw-r--r--db2/mp/mp_open.c41
-rw-r--r--db2/mutex/mutex.c2
-rw-r--r--db2/os/db_os_dir.c8
-rw-r--r--db2/progs/db_checkpoint/db_checkpoint.c25
-rw-r--r--db2/progs/db_deadlock/db_deadlock.c2
-rw-r--r--db2/progs/db_dump185/db_dump185.c4
-rw-r--r--db2/progs/db_load/db_load.c4
-rw-r--r--db2/progs/db_recover/db_recover.c3
-rw-r--r--db2/txn/txn.c195
-rw-r--r--db2/txn/txn_auto.c4
-rw-r--r--elf/link.h14
-rw-r--r--elf/sofini.c2
-rw-r--r--elf/soinit.c2
-rw-r--r--include/features.h15
-rw-r--r--intl/dcgettext.c25
-rw-r--r--intl/finddomain.c20
-rw-r--r--intl/gettextP.h3
-rw-r--r--intl/loadmsgcat.c17
-rw-r--r--intl/localealias.c77
-rw-r--r--libc.map10
-rw-r--r--libio/Makefile2
-rw-r--r--libio/fseeko.c42
-rw-r--r--libio/ftello.c50
-rw-r--r--libio/stdio.h11
-rw-r--r--locale/C-collate.c2
-rw-r--r--locale/C-ctype.c2
-rw-r--r--locale/C-messages.c2
-rw-r--r--locale/C-monetary.c2
-rw-r--r--locale/C-numeric.c2
-rw-r--r--locale/C-time.c2
-rw-r--r--locale/findlocale.c27
-rw-r--r--locale/loadlocale.c11
-rw-r--r--locale/localeinfo.h6
-rw-r--r--locale/programs/localedef.c2
-rw-r--r--malloc/Makefile3
-rw-r--r--malloc/mtrace.c27
-rw-r--r--malloc/set-freeres.c33
-rw-r--r--manual/creature.texi4
-rw-r--r--manual/llio.texi65
-rw-r--r--manual/stdio.texi117
-rw-r--r--misc/hsearch.c6
-rw-r--r--misc/sys/select.h4
-rw-r--r--nis/nis_call.c3
-rw-r--r--nis/nis_mkdir.c24
-rw-r--r--nis/nis_rmdir.c22
-rw-r--r--nis/rpcsvc/yp_prot.h20
-rw-r--r--posix/Makefile3
-rw-r--r--posix/sys/types.h22
-rw-r--r--posix/unistd.h90
-rw-r--r--resolv/resolv.h4
-rw-r--r--set-init.c2
-rw-r--r--stdlib/fmtmsg.c26
-rw-r--r--stdlib/tst-strtol.c2
-rw-r--r--string/bits/string2.h38
-rw-r--r--string/strings.h36
-rw-r--r--string/swab.c5
-rw-r--r--sunrpc/clnt_simp.c2
-rw-r--r--sunrpc/rpc/auth_des.h11
-rw-r--r--sysdeps/i386/i486/bits/string.h234
-rw-r--r--sysdeps/m68k/fpu/bits/mathinline.h2
-rw-r--r--sysdeps/m68k/fpu/s_exp2.c4
-rw-r--r--sysdeps/m68k/fpu/s_exp2f.c4
-rw-r--r--sysdeps/m68k/fpu/s_exp2l.c4
-rw-r--r--sysdeps/mach/hurd/cthreads.c18
-rw-r--r--sysdeps/posix/pread.c56
-rw-r--r--sysdeps/posix/pwrite.c56
-rw-r--r--sysdeps/stub/pread.c43
-rw-r--r--sysdeps/stub/pwrite.c43
-rw-r--r--sysdeps/unix/sysv/linux/Makefile3
-rw-r--r--sysdeps/unix/sysv/linux/scsi/sg.h59
-rw-r--r--sysdeps/unix/sysv/linux/sys/mman.h2
-rw-r--r--sysdeps/unix/sysv/linux/syscalls.list2
-rw-r--r--time/strftime.c8
-rw-r--r--time/time.h89
138 files changed, 2410 insertions, 1208 deletions
diff --git a/BUGS b/BUGS
index 520311f9f4..10f72edabd 100644
--- a/BUGS
+++ b/BUGS
@@ -1,7 +1,7 @@
 	    List of known bugs (certainly very incomplete)
 	    ----------------------------------------------
 
-Time-stamp: <1997-09-06T18:30:16+0200 drepper>
+Time-stamp: <1997-09-28T22:58:35+0200 drepper>
 
 This following list contains those bugs which I'm aware of.  Please
 make sure that bugs you report are not listed here.  If you can fix one
@@ -56,6 +56,20 @@ Severity: [  *] to [***]
 [  *]  The rcmd() functions (more concrete: the handling of .rhosts) does
        not support netgroups and wildcards (+).
 
+[  *]  The first alias definition in locale.alias is ignored.
+       [PR libc/205]
+
+[  *]  When assembling a locale definition, that uses the "copy"
+       directive, with localedef, not only the copied category is
+       checked for errors, but the whole file containing the same
+       category.
+       [PR libc/207]
+
+[  *]  configuring with CFLAGS="-pipe" configure doesn't work
+       with gcc. This seems to be a bug in gcc 2.7.2.x (egcs doesn't
+       have this bug).
+       [PR libc/245]
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Ulrich Drepper
 drepper@cygnus.com
diff --git a/ChangeLog b/ChangeLog
index 7e94c28c7b..e78451a71f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,221 @@
+1997-09-30 18:03  Ulrich Drepper  <drepper@cygnus.com>
+
+	* Makerules: Undo last change.
+	* csu/Makefile: Define before-compile at the right place.
+
+	* aclocal.m4: Remove a.out file created by assembler test.
+
+	* set-init.c: Find set-hooks.h using <...>.
+
+	Update to db 2.3.10.
+	* db2/Makefile: Update.
+	* db2/db.h: Likewise.
+	* db2/db_185.h: Likewise.
+	* db2/db_int.h: Likewise.
+	* db2/btree/bt_close.c: Likewise.
+	* db2/btree/bt_conv.c: Likewise.
+	* db2/btree/bt_cursor.c: Likewise.
+	* db2/btree/bt_put.c: Likewise.
+	* db2/btree/bt_rec.c: Likewise.
+	* db2/btree/bt_recno.c: Likewise.
+	* db2/btree/btree.src: Likewise.
+	* db2/btree/btree_auto.c: Likewise.
+	* db2/clib/getlong.c: Likewise.
+	* db2/db/db.c: Likewise.
+	* db2/db/db_auto.c: Likewise.
+	* db2/db/db_conv.c: Likewise.
+	* db2/db/db_pr.c: Likewise.
+	* db2/db/db_ret.c: Likewise.
+	* db2/db/db_thread.c: Likewise.
+	* db2/hash/hash.c: Likewise.
+	* db2/hash/hash_auto.c: Likewise.
+	* db2/hash/hash_conv.c: Likewise.
+	* db2/hash/hash_dup.c: Likewise.
+	* db2/hash/hash_func.c: Likewise.
+	* db2/hash/hash_page.c: Likewise.
+	* db2/hash/hash_rec.c: Likewise.
+	* db2/include/btree.h: Likewise.
+	* db2/include/btree_ext.h: Likewise.
+	* db2/include/db.h.src: Likewise.
+	* db2/include/db_185.h.src: Likewise.
+	* db2/include/db_cxx.h: Likewise.
+	* db2/include/db_ext.h: Likewise.
+	* db2/include/db_int.h.src: Likewise.
+	* db2/include/db_page.h: Likewise.
+	* db2/include/db_shash.h: Likewise.
+	* db2/include/lock.h: Likewise.
+	* db2/include/log.h: Likewise.
+	* db2/include/log_ext.h: Likewise.
+	* db2/include/mp.h: Likewise.
+	* db2/include/shqueue.h: Likewise.
+	* db2/include/txn.h: Likewise.
+	* db2/lock/lock.c: Likewise.
+	* db2/lock/lock_deadlock.c: Likewise.
+	* db2/log/log.c: Likewise.
+	* db2/log/log_archive.c: Likewise.
+	* db2/log/log_auto.c: Likewise.
+	* db2/log/log_get.c: Likewise.
+	* db2/log/log_put.c: Likewise.
+	* db2/log/log_register.c: Likewise.
+	* db2/mp/mp_bh.c: Likewise.
+	* db2/mp/mp_fget.c: Likewise.
+	* db2/mp/mp_fopen.c: Likewise.
+	* db2/mp/mp_fput.c: Likewise.
+	* db2/mp/mp_fset.c: Likewise.
+	* db2/mp/mp_open.c: Likewise.
+	* db2/mutex/mutex.c: Likewise.
+	* db2/os/db_os_dir.c: Likewise.
+	* db2/progs/db_checkpoint/db_checkpoint.c: Likewise.
+	* db2/progs/db_deadlock/db_deadlock.c: Likewise.
+	* db2/progs/db_dump185/db_dump185.c: Likewise.
+	* db2/progs/db_load/db_load.c: Likewise.
+	* db2/progs/db_recover/db_recover.c: Likewise.
+	* db2/txn/txn.c: Likewise.
+	* db2/txn/txn_auto.c: Likewise.
+
+	* elf/link.h: Define struct libname_list outside struct link_map
+	to not confuse C++ compilers.
+
+	* include/features.h: Recognize _XOPEN_SOURCE == 500 and set
+	__USE_UNIX98.
+	* manual/creature.texi: Explain this.
+
+	* libc.map: Add new functions.
+
+	* libio/Makefile (routines): Add fseeko and ftello.
+	* libio/ftello.c: New file.
+	* libio/fseeko.c: New file.
+	* libio/stdio.h: Add prototypes for new functions.
+	* manual/stdio.texi: Document fseeko and ftello.
+
+	* posix/Makefile (routines): Add pread and pwrite.
+	* sysdeps/posix/pread.c: New file.
+	* sysdeps/posix/pwrite.c: New file.
+	* sysdeps/stub/pread.c: New file.
+	* sysdeps/stub/pwrite.c: New file.
+	* posix/unistd.h: Add prototypes for pread and pwrite.
+	Pretty print header.
+	Define gid_t, uid_t, off_t, pid_t if __USE_UNIX98.
+	Declare ctermid and cuserid if __USE_UNIX98.
+	(swab): Change to take void * arguments.
+	* string/swab.c: Change parameter to void *.
+	* posix/sys/types: Define gid_t, uid_t, off_t, pid_t only if not
+	already happened.
+	* manual/llio.texi: Document pread and pwrite.
+
+	* string/strings.h: Don't simply include string.h.  Define BSD
+	functions according to Unix98.
+	* stdlib/tst-strtol.c: Include <string.h> not <strings.h>.
+	* sunrpc/clnt_simp.c: Likewise.
+
+	* malloc/Makefile (aux): Add set-freeres.
+	* malloc/mtrace.c: Define function release_libc_mem which calls the
+	__libc_subfreeres handler.
+	(mtrace): Register release_libc_mem.
+	* malloc/set-freeres.c: New file.
+
+	* intl/dcgettext.c: Define free_mem function and add to
+	__libc_subfreeres list.
+	* intl/finddomain.c: Likewise.
+	* intl/gettextP.h (struct loaded_domain): Add new fields use_mmap
+	and mmap_size.  Add prototype for _nl_unloaded_domain.
+	* intl/loadmsgcat.c: Define new function _nl_unload_domain.
+	(_nl_load_domain): Store informaiton about mmap use and file size.
+	* intl/localealias.c (read_alias_file): Optimize locale alias file
+	reading by avoid frequen mallocs.
+	Define free_mem function and add to __libc_subfreeres list.
+
+	* locale/localeinfo.h: Make a difference between MAX_USAGE_COUNT and
+	undeletable.
+	Add prototype for _nl_unload_locale.
+	* locale/C-collate: Mark data as undeletable by using UNDELETABLE.
+	* locale/C-ctype: Likewise.
+	* locale/C-messages: Likewise.
+	* locale/C-monetary: Likewise.
+	* locale/C-numeric: Likewise.
+	* locale/C-time: Likewise.
+	* locale/findlocale.c (_nl_find_locale, _nl_remove_locale): Handle
+	MAX_USAGE_COUNT and UNDELETABLE.
+	(free_mem): New function.  Add it to __libc_subfreeres list.
+	* locale/loadlocale.c: Define _nl_unload_locale function.
+
+	* misc/hsearch.c: Register hdestroy in __libc_subfreeres list.
+
+	* stdlib/fmtmsg.c (addseverity): Handle illegal severity arguments
+	correctly
+	Define free_mem function and add to __libc_subfreeres list.
+
+	* locale/programs/localedef.c (options): short form os verbose is v.
+	Reported by Andreas Jaeger.
+
+	* misc/sys/select.h: Define pselect only is __USE_POSIX since this
+	header is used in some others as well for historical reasons.
+
+	* resolv/resolv.h: Include <netinet/in.h> to make self-contained.
+
+	* string/bits/string2.h: Add missing braces and optimize strcmp a
+	bit more.
+	* sysdeps/i386/i486/bits/string.h: Likewise.
+
+	* sunrpc/rpc/auth_des.h: Include rpc/auth.h to be self-contained.
+	Pretty print.
+
+	* sysdeps/mach/hurd/cthreads.c: Add copyright text.
+
+	* sysdeps/unix/sysv/linux/syscalls.list: Correct prctl entry.
+
+	* sysdeps/unix/sysv/linux/sys/mman.h: Get definition of size_t.
+
+	* time/time.h: Pretty print.
+
+1997-09-29  Paul Eggert  <eggert@twinsun.com>
+
+	* time/strftime.c: Synchronize with GNU Emacs strftime.c.
+	(HAVE_MEMCPY): Define if emacs is defined and HAVE_BCOPY isn't.
+	(gmtime_r, localtime_r): Undef before defining.
+	(iso_week_days): Use __inline__, not inline.
+
+1997-09-27  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* sysdeps/m68k/fpu/bits/mathinline.h: Rename exp2{,l,f} to
+	__ieee754_exp2{,l,f}.
+	* sysdeps/m68k/fpu/s_exp2.c: Likewise.
+	* sysdeps/m68k/fpu/s_exp2l.c: Likewise.
+	* sysdeps/m68k/fpu/s_exp2f.c: Likewise.
+
+1997-09-27  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+	* elf/soinit.c (__EH_FRAME_BEGIN__): Don't make the .eh_frame
+	section read-only, it contains relocations.
+	* elf/sofini.c (__FRAME_END__): Likewise.
+
+1997-09-29 03:08  Ulrich Drepper  <drepper@cygnus.com>
+
+	* sysdeps/i386/i486/bits/string.h [__PIC__] (__strspn_cg, __strcspn_cg,
+	__strpbrk_cg, __strstr_cg): Optimize even more.  No spill register
+	needed.  Patch by NIIBE Yutaka <gniibe@mri.co.jp>.
+
+1997-09-28 08:27  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>
+
+	* nis/nis_call.c (__do_niscall2): Fix return code, add missing
+	  break in switch case.
+
+	* nis/nis_mkdir.c: Fix return codes to match Solaris version.
+	* nis/nis_rmdir.c: Likewise.
+
+	* nis/rpcsvc/yp_prot.h: Rename struct keydat to struct keydat_t
+	for C++.
+
+1997-09-28 04:32  Ulrich Drepper  <drepper@cygnus.com>
+
+	* configure.in: Fix typo.
+	Patch by Zack Weinberg <zack@rabi.phys.columbia.edu>.
+
+1997-09-25 20:14  Philip Blundell  <Philip.Blundell@pobox.com>
+
+	* sysdeps/unix/sysv/linux/scsi/sg.h: New file.
+	* sysdeps/unix/sysv/linux/Makefile: Install <scsi/sg.h>.
+
 1997-09-27 01:14  Ulrich Drepper  <drepper@cygnus.com>
 
 	* Makeconfig (extra-objs): Depend in before-compile.
diff --git a/FAQ b/FAQ
index 568af9f207..bba8bef434 100644
--- a/FAQ
+++ b/FAQ
@@ -90,6 +90,9 @@ please let me know.
 
 [Q25]	``After installing glibc name resolving doesn't work properly.''
 
+
+[Q26]	``I have /usr/include/net and /usr/include/scsi as symlinks
+	  into my Linux source tree.  Is that wrong?''
 
 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 [Q1]	``What systems does the GNU C Library run on?''
@@ -652,7 +655,7 @@ results because of type conflicts.
 a point where it is stable.  There are still lots of incompatible changes
 made and the libc headers have to follow.
 
-Currently (as of 970401) according to Philip Blundell <pjb27@cam.ac.uk>
+Currently (as of 970401) according to Philip Blundell <philb@gnu.ai.mit.edu>
 the required kernel version is 2.1.30.
 
 
@@ -698,6 +701,18 @@ The NSS configuration file is usually the culprit.
 
 
 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+[Q26]	``I have /usr/include/net and /usr/include/scsi as symlinks
+	  into my Linux source tree.  Is that wrong?''
+
+[A26] {PB} This was necessary for libc5, but is not correct when using
+glibc.  Including the kernel header files directly in user programs
+usually does not work (see Q21).  glibc provides its own <net/*> and
+<scsi/*> header files to replace them, and you may have to remove any
+symlink that you have in place before you install glibc.  However,
+/usr/include/asm and /usr/include/linux should remain as they were.
+
+
+~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
 
 Answers were given by:
 {UD} Ulrich Drepper, <drepper@cygnus.com>
@@ -706,6 +721,7 @@ Answers were given by:
 {HJL} H.J. Lu, <hjl@gnu.ai.mit.edu>
 {AJ} Andreas Jaeger, <aj@arthur.rhein-neckar.de>
 {EY} Eric Youngdale, <eric@andante.jic.com>
+{PB} Phil Blundell, <Philip.Blundell@pobox.com>
 
 Local Variables:
  mode:text
diff --git a/Makerules b/Makerules
index abfb8ef85e..948c01b89d 100644
--- a/Makerules
+++ b/Makerules
@@ -701,10 +701,6 @@ $(inst_slibdir)/libc.so: $(common-objpfx)libc.so
 	$(do-install-program)
 endif
 
-ifdef extra-objs
-$(addprefix $(objpfx),$(extra-objs)): $(before-compile)
-endif
-
 ifneq (,$(versioned))
 # Produce three sets of rules as above for all the smaller versioned libraries.
 
diff --git a/NEWS b/NEWS
index dfd3cd7ecc..d02e78465c 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  1997-03-18
+GNU C Library NEWS -- history of user-visible changes.  1997-09-27
 
 Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
 See the end for copying conditions.
@@ -31,11 +31,31 @@ Version 2.1
 * the new header <complex.h> contains definitions of the complex math
   functions from ISO C 9X
 
-* Thorsten Kukuk provided an implementation for NIS+, securelevel 0 and 1.
-  The implementation for securelevel 2 will follow as soon as the Diffie-
-  Hellman patent expired.
+* Thorsten Kukuk provided an implementation for NIS+, securelevel 0, 1 and 2.
 
-* Andreas Jaeger provided a test suite for the math library
+* Andreas Jaeger provided a test suite for the math library.
+
+* Mark Kettenis implemented the utmpx interface and an utmp daemon.
+
+Version 2.0.5
+
+* more bug fixes
+
+* inet_ntoa is thread-safe
+
+* updwtmp is moved from libutil to libc
+
+* rewrite of cbrt function
+
+* update of timezone data
+
+Version 2.0.4
+
+* more bug fixes
+
+Version 2.0.3
+
+* more bug fixes
 
 Version 2.0.2
 
diff --git a/aclocal.m4 b/aclocal.m4
index 3c8e794d21..582e0a8e7b 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -113,6 +113,7 @@ LD=`$CC -print-file-name=ld`
 # Determine whether we are using GNU binutils.
 AC_CACHE_CHECK(whether $AS is GNU as, libc_cv_prog_as_gnu,
 [LIBC_PROG_FOO_GNU($AS, libc_cv_prog_as_gnu=yes, libc_cv_prog_as_gnu=no)])
+rm -f a.out
 gnu_as=$libc_cv_prog_as_gnu
 
 AC_CACHE_CHECK(whether $LD is GNU ld, libc_cv_prog_ld_gnu,
diff --git a/configure b/configure
index 5060a9adc7..2ab552c309 100755
--- a/configure
+++ b/configure
@@ -27,8 +27,7 @@ ac_help="$ac_help
 ac_help="$ac_help
   --with-fp		  if using floating-point hardware [default=yes]"
 ac_help="$ac_help
-  --with-binutils=PATH	  specify location of binutils (as and ld)
-	    path_binutils=$withval"
+  --with-binutils=PATH	  specify location of binutils (as and ld)"
 ac_help="$ac_help
   --with-elf		  if using the ELF object format"
 ac_help="$ac_help
@@ -613,6 +612,8 @@ fi
 # Check whether --with-binutils or --without-binutils was given.
 if test "${with_binutils+set}" = set; then
   withval="$with_binutils"
+  path_binutils=$withval
+else
   path_binutils=''
 fi
 
@@ -754,7 +755,7 @@ 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:758: checking host system type" >&5
+echo "configure:759: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -866,7 +867,7 @@ esac
 # This can take a while to compute.
 sysdep_dir=$srcdir/sysdeps
 echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
-echo "configure:870: checking sysdep dirs" >&5
+echo "configure:871: checking sysdep dirs" >&5
 # Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
 os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
 
@@ -1067,7 +1068,7 @@ echo "$ac_t""sysdeps/generic sysdeps/stub" 1>&6
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1071: checking for a BSD compatible install" >&5
+echo "configure:1072: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1121,7 +1122,7 @@ if test "$INSTALL" = "${srcdir}/install-sh -c"; then
   INSTALL='\$(..)./install-sh -c'
 fi
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1125: checking whether ln -s works" >&5
+echo "configure:1126: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1146,7 +1147,7 @@ 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:1150: checking for $ac_word" >&5
+echo "configure:1151: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1179,7 +1180,7 @@ test -n "$MSGFMT" || MSGFMT=":"
 # 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:1183: checking for $ac_word" >&5
+echo "configure:1184: 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
@@ -1208,7 +1209,7 @@ 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:1212: checking for $ac_word" >&5
+echo "configure:1213: 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
@@ -1256,7 +1257,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1260: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1261: 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.
@@ -1266,11 +1267,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS
 cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext <<EOF
-#line 1270 "configure"
+#line 1271 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-if { (eval echo configure:1274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; 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
@@ -1293,13 +1294,13 @@ else
  cross_linkable=yes
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:1297: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1298: 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:1303: checking whether we are using GNU C" >&5
+echo "configure:1304: 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
@@ -1308,7 +1309,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1312: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1313: \"$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
@@ -1325,7 +1326,7 @@ if test $ac_cv_prog_gcc = yes; then
   yes;
 #endif
 EOF
-  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1329: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1330: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
     if test -z "$CFLAGS"; then
       CFLAGS="-g -O2"
     fi
@@ -1337,7 +1338,7 @@ else
 fi
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1341: checking build system type" >&5
+echo "configure:1342: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -1360,7 +1361,7 @@ 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:1364: checking for $ac_word" >&5
+echo "configure:1365: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1391,7 +1392,7 @@ done
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1395: checking how to run the C preprocessor" >&5
+echo "configure:1396: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1406,13 +1407,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1410 "configure"
+#line 1411 "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:1416: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1417: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1423,13 +1424,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1427 "configure"
+#line 1428 "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:1433: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1434: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1462,7 +1463,7 @@ LD=`$CC -print-file-name=ld`
 
 # Determine whether we are using GNU binutils.
 echo $ac_n "checking whether $AS is GNU as""... $ac_c" 1>&6
-echo "configure:1466: checking whether $AS is GNU as" >&5
+echo "configure:1467: checking whether $AS is GNU as" >&5
 if eval "test \"`echo '$''{'libc_cv_prog_as_gnu'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1476,10 +1477,11 @@ fi
 fi
 
 echo "$ac_t""$libc_cv_prog_as_gnu" 1>&6
+rm -f a.out
 gnu_as=$libc_cv_prog_as_gnu
 
 echo $ac_n "checking whether $LD is GNU ld""... $ac_c" 1>&6
-echo "configure:1483: checking whether $LD is GNU ld" >&5
+echo "configure:1485: checking whether $LD is GNU ld" >&5
 if eval "test \"`echo '$''{'libc_cv_prog_ld_gnu'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1503,7 +1505,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ar; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1507: checking for $ac_word" >&5
+echo "configure:1509: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1534,7 +1536,7 @@ fi
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1538: checking for $ac_word" >&5
+echo "configure:1540: 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
@@ -1565,7 +1567,7 @@ if test -n "$ac_tool_prefix"; then
   # 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:1569: checking for $ac_word" >&5
+echo "configure:1571: 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
@@ -1600,7 +1602,7 @@ fi
 # Extract the first word of "bash", so it can be a program name with args.
 set dummy bash; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1604: checking for $ac_word" >&5
+echo "configure:1606: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1641,7 +1643,7 @@ if test "$BASH" = no; then
   # Extract the first word of "ksh", so it can be a program name with args.
 set dummy ksh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1645: checking for $ac_word" >&5
+echo "configure:1647: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1687,7 +1689,7 @@ 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:1691: checking for $ac_word" >&5
+echo "configure:1693: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1722,7 +1724,7 @@ test -n "$PERL" || PERL="no"
 
 
 echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
-echo "configure:1726: checking for signed size_t type" >&5
+echo "configure:1728: checking for signed size_t type" >&5
 if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1746,12 +1748,12 @@ EOF
 fi
 
 echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
-echo "configure:1750: checking for libc-friendly stddef.h" >&5
+echo "configure:1752: checking for libc-friendly stddef.h" >&5
 if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1755 "configure"
+#line 1757 "configure"
 #include "confdefs.h"
 #define __need_size_t
 #define __need_wchar_t
@@ -1766,7 +1768,7 @@ size_t size; wchar_t wchar;
 if (&size == NULL || &wchar == NULL) abort ();
 ; return 0; }
 EOF
-if { (eval echo configure:1770: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1772: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_friendly_stddef=yes
 else
@@ -1785,7 +1787,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
 fi
 
 echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
-echo "configure:1789: checking whether we need to use -P to assemble .S files" >&5
+echo "configure:1791: checking whether we need to use -P to assemble .S files" >&5
 if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1808,7 +1810,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
 fi
 
 echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
-echo "configure:1812: checking for assembler global-symbol directive" >&5
+echo "configure:1814: checking for assembler global-symbol directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1838,7 +1840,7 @@ EOF
 fi
 
 echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
-echo "configure:1842: checking for .set assembler directive" >&5
+echo "configure:1844: checking for .set assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1872,7 +1874,7 @@ EOF
 fi
 
 echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
-echo "configure:1876: checking for .symver assembler directive" >&5
+echo "configure:1878: checking for .symver assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1891,7 +1893,7 @@ fi
 
 echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
 echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
-echo "configure:1895: checking for ld --version-script" >&5
+echo "configure:1897: checking for ld --version-script" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1910,7 +1912,7 @@ EOF
     if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
 					-nostartfiles -nostdlib
 					-Wl,--version-script,conftest.map
-		       1>&5'; { (eval echo configure:1914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
+		       1>&5'; { (eval echo configure:1916: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
     then
       libc_cv_ld_version_script_option=yes
     else
@@ -1941,7 +1943,7 @@ fi
 
 if test $elf = yes; then
   echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
-echo "configure:1945: checking for .previous assembler directive" >&5
+echo "configure:1947: checking for .previous assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1949,7 +1951,7 @@ else
 .section foo_section
 .previous
 EOF
-  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1953: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+  if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1955: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
     libc_cv_asm_previous_directive=yes
   else
     libc_cv_asm_previous_directive=no
@@ -1965,7 +1967,7 @@ EOF
 
   else
     echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
-echo "configure:1969: checking for .popsection assembler directive" >&5
+echo "configure:1971: checking for .popsection assembler directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1973,7 +1975,7 @@ else
 .pushsection foo_section
 .popsection
 EOF
-    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1977: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+    if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:1979: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
       libc_cv_asm_popsection_directive=yes
     else
       libc_cv_asm_popsection_directive=no
@@ -1993,12 +1995,12 @@ fi
 
 if test $elf != yes; then
   echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
-echo "configure:1997: checking for .init and .fini sections" >&5
+echo "configure:1999: checking for .init and .fini sections" >&5
 if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2002 "configure"
+#line 2004 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2007,7 +2009,7 @@ asm (".section .init");
 				    asm (".text");
 ; return 0; }
 EOF
-if { (eval echo configure:2011: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2013: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   libc_cv_have_initfini=yes
 else
@@ -2035,19 +2037,19 @@ if test $elf = yes; then
 else
   if test $ac_cv_prog_cc_works = yes; then
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2039: checking for _ prefix on C symbol names" >&5
+echo "configure:2041: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2044 "configure"
+#line 2046 "configure"
 #include "confdefs.h"
 asm ("_glibc_foobar:");
 int main() {
 glibc_foobar ();
 ; return 0; }
 EOF
-if { (eval echo configure:2051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   libc_cv_asm_underscores=yes
 else
@@ -2062,17 +2064,17 @@ fi
 echo "$ac_t""$libc_cv_asm_underscores" 1>&6
   else
     echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
-echo "configure:2066: checking for _ prefix on C symbol names" >&5
+echo "configure:2068: checking for _ prefix on C symbol names" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2071 "configure"
+#line 2073 "configure"
 #include "confdefs.h"
 void underscore_test(void) {
 return; }
 EOF
-if { (eval echo configure:2076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2078: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   if grep _underscore_test conftest* >/dev/null; then
     rm -f conftest*
     libc_cv_asm_underscores=yes
@@ -2105,7 +2107,7 @@ if test $elf = yes; then
   libc_cv_asm_weakext_directive=no
 else
   echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
-echo "configure:2109: checking for assembler .weak directive" >&5
+echo "configure:2111: checking for assembler .weak directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2128,7 +2130,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
 
 if test $libc_cv_asm_weak_directive = no; then
   echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
-echo "configure:2132: checking for assembler .weakext directive" >&5
+echo "configure:2134: checking for assembler .weakext directive" >&5
 if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2165,7 +2167,7 @@ EOF
 fi
 
 echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
-echo "configure:2169: checking for ld --no-whole-archive" >&5
+echo "configure:2171: checking for ld --no-whole-archive" >&5
 if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2176,7 +2178,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -Wl,--no-whole-archive
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2180: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_ld_no_whole_archive=yes
 else
   libc_cv_ld_no_whole_archive=no
@@ -2187,7 +2189,7 @@ fi
 echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
 
 echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
-echo "configure:2191: checking for gcc -fno-exceptions" >&5
+echo "configure:2193: checking for gcc -fno-exceptions" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2198,7 +2200,7 @@ __throw () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles -fno-exceptions
-			    -o conftest conftest.c 1>&5'; { (eval echo configure:2202: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c 1>&5'; { (eval echo configure:2204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_no_exceptions=yes
 else
   libc_cv_gcc_no_exceptions=no
@@ -2209,12 +2211,12 @@ fi
 echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6
 
 echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
-echo "configure:2213: checking for DWARF2 unwind info support" >&5
+echo "configure:2215: checking for DWARF2 unwind info support" >&5
 if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.c <<EOF
-#line 2218 "configure"
+#line 2220 "configure"
 static char __EH_FRAME_BEGIN__;
 _start ()
 {
@@ -2234,7 +2236,7 @@ abort () {}
 EOF
 if { ac_try='${CC-cc} $CFLAGS
 			    -nostdlib -nostartfiles
-			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
+			    -o conftest conftest.c -lgcc >&5'; { (eval echo configure:2240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
   libc_cv_gcc_dwarf2_unwind_info=yes
 else
   libc_cv_gcc_dwarf2_unwind_info=no
@@ -2292,7 +2294,7 @@ if test "$uname" = "sysdeps/generic"; then
   fi
 
   echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
-echo "configure:2296: checking OS release for uname" >&5
+echo "configure:2298: checking OS release for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2314,7 +2316,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
   uname_release="$libc_cv_uname_release"
 
   echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
-echo "configure:2318: checking OS version for uname" >&5
+echo "configure:2320: checking OS version for uname" >&5
 if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2336,7 +2338,7 @@ else
 fi
 
 echo $ac_n "checking stdio selection""... $ac_c" 1>&6
-echo "configure:2340: checking stdio selection" >&5
+echo "configure:2342: checking stdio selection" >&5
 
 case $stdio in
 libio) cat >> confdefs.h <<\EOF
@@ -2348,7 +2350,7 @@ esac
 echo "$ac_t""$stdio" 1>&6
 
 echo $ac_n "checking ldap selection""... $ac_c" 1>&6
-echo "configure:2352: checking ldap selection" >&5
+echo "configure:2354: checking ldap selection" >&5
 
 case $add_ons in
 *ldap*)
diff --git a/configure.in b/configure.in
index efa338c3ee..b0bb90543a 100644
--- a/configure.in
+++ b/configure.in
@@ -37,7 +37,7 @@ AC_ARG_WITH(fp, dnl
 [  --with-fp		  if using floating-point hardware [default=yes]],
 	    with_fp=$withval, with_fp=yes)
 AC_ARG_WITH(binutils, dnl
-  --with-binutils=PATH	  specify location of binutils (as and ld)
+  --with-binutils=PATH	  specify location of binutils (as and ld),
 	    path_binutils=$withval, path_binutils='')
 AC_ARG_WITH(elf, dnl
   --with-elf		  if using the ELF object format,
diff --git a/csu/Makefile b/csu/Makefile
index 8388032e1d..bc66f674bc 100644
--- a/csu/Makefile
+++ b/csu/Makefile
@@ -32,9 +32,6 @@ csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o)
 extra-objs = start.o gmon-start.o \
 	     $(start-installed-name) g$(start-installed-name) \
 	     $(csu-dummies)
-ifeq ($(elf),yes)
-before-compile = $(objpfx)abi-tag.h
-endif
 omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \
 		             $(csu-dummies))
 install-lib = $(start-installed-name) g$(start-installed-name) \
@@ -45,6 +42,9 @@ all: # Make this the default target; it will be defined in Rules.
 
 include ../Makeconfig
 
+ifeq ($(elf),yes)
+before-compile = $(objpfx)abi-tag.h
+endif
 
 ifeq ($(have-initfini),yes)
 
diff --git a/db2/Makefile b/db2/Makefile
index a75dc5aef1..e6b35aa51b 100644
--- a/db2/Makefile
+++ b/db2/Makefile
@@ -19,7 +19,7 @@
 #
 #	Sub-makefile for libdb.
 #
-#	The code is lifted straight from the db 2.3.6 distribution
+#	The code is lifted straight from the db 2.3.10 distribution
 #	with minimal changes.
 #
 
diff --git a/db2/btree/bt_close.c b/db2/btree/bt_close.c
index 7044599dd2..7dd7139c66 100644
--- a/db2/btree/bt_close.c
+++ b/db2/btree/bt_close.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_close.c	10.23 (Sleepycat) 9/2/97";
+static const char sccsid[] = "@(#)bt_close.c	10.24 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -150,7 +150,7 @@ __bam_upstat(dbp)
 
 	/*
 	 * We use a no-op log call to log the update of the statistics onto the
-	 * metadata page.  The dbp->close() call isn't transaction protected to
+	 * metadata page.  The Db->close call isn't transaction protected to
 	 * start with, and I'm not sure what undoing a statistics update means,
 	 * anyway.
 	 */
diff --git a/db2/btree/bt_conv.c b/db2/btree/bt_conv.c
index c9d5d1bc3e..c89493cbed 100644
--- a/db2/btree/bt_conv.c
+++ b/db2/btree/bt_conv.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_conv.c	10.4 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_conv.c	10.5 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -21,12 +21,11 @@ static const char sccsid[] = "@(#)bt_conv.c	10.4 (Sleepycat) 9/3/97";
 #include "btree.h"
 
 /*
- * __bam_pgin, __bam_pgout --
- *	Convert host-specific page layout to/from the host-independent
- *	format stored on disk.
+ * __bam_pgin --
+ *	Convert host-specific page layout from the host-independent format
+ *	stored on disk.
  *
  * PUBLIC: int __bam_pgin __P((db_pgno_t, void *, DBT *));
- * PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *));
  */
 int
 __bam_pgin(pg, pp, cookie)
@@ -39,9 +38,17 @@ __bam_pgin(pg, pp, cookie)
 	pginfo = (DB_PGINFO *)cookie->data;
 	if (!pginfo->needswap)
 		return (0);
-	return (pg == PGNO_METADATA ? __bam_mswap(pp) : __db_pgin(pg, pp));
+	return (pg == PGNO_METADATA ?
+	    __bam_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp));
 }
 
+/*
+ * __bam_pgout --
+ *	Convert host-specific page layout to the host-independent format
+ *	stored on disk.
+ *
+ * PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *));
+ */
 int
 __bam_pgout(pg, pp, cookie)
 	db_pgno_t pg;
@@ -53,7 +60,8 @@ __bam_pgout(pg, pp, cookie)
 	pginfo = (DB_PGINFO *)cookie->data;
 	if (!pginfo->needswap)
 		return (0);
-	return (pg == PGNO_METADATA ? __bam_mswap(pp) : __db_pgout(pg, pp));
+	return (pg == PGNO_METADATA ?
+	    __bam_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp));
 }
 
 /*
diff --git a/db2/btree/bt_cursor.c b/db2/btree/bt_cursor.c
index efae556030..a1266bcd3c 100644
--- a/db2/btree/bt_cursor.c
+++ b/db2/btree/bt_cursor.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_cursor.c	10.27 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_cursor.c	10.33 (Sleepycat) 9/24/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -81,7 +81,10 @@ __bam_cursor(dbp, txn, dbcp)
 	dbc->c_get = __bam_c_get;
 	dbc->c_put = __bam_c_put;
 
-	/* All cursor structures hang off the main DB structure. */
+	/*
+	 * All cursors are queued from the master DB structure.  Add the
+	 * cursor to that queue.
+	 */
 	DB_THREAD_LOCK(dbp);
 	TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links);
 	DB_THREAD_UNLOCK(dbp);
@@ -99,31 +102,53 @@ __bam_c_close(dbc)
 	DBC *dbc;
 {
 	DB *dbp;
-	CURSOR *cp;
 	int ret;
 
 	DEBUG_LWRITE(dbc->dbp, dbc->txn, "bam_c_close", NULL, NULL, 0);
 
 	GETHANDLE(dbc->dbp, dbc->txn, &dbp, ret);
+
+	ret = __bam_c_iclose(dbp, dbc);
+
+	PUTHANDLE(dbp);
+	return (ret);
+}
+
+/*
+ * __bam_c_iclose --
+ *	Close a single cursor -- internal version.
+ *
+ * PUBLIC: int __bam_c_iclose __P((DB *, DBC *));
+ */
+int
+__bam_c_iclose(dbp, dbc)
+	DB *dbp;
+	DBC *dbc;
+{
+	CURSOR *cp;
+	int ret;
+
 	cp = dbc->internal;
 
-	/* If a cursor key was deleted do the actual deletion.  */
-	ret = F_ISSET(cp, C_DELETED) ?  __bam_c_physdel(dbp, cp, NULL) : 0;
+	/* If a cursor key was deleted, perform the actual deletion.  */
+	ret = F_ISSET(cp, C_DELETED) ? __bam_c_physdel(dbp, cp, NULL) : 0;
 
 	/* Discard any lock if we're not inside a transaction. */
-	if (dbp->txn == NULL && cp->lock != LOCK_INVALID)
+	if (cp->lock != LOCK_INVALID)
 		(void)__BT_TLPUT(dbp, cp->lock);
 
-	/* Remove the cursor from the queue. */
-	DB_THREAD_LOCK(dbp);
-	TAILQ_REMOVE(&dbp->curs_queue, dbc, links);
-	DB_THREAD_UNLOCK(dbp);
+	/*
+	 * All cursors are queued from the master DB structure.  Remove the
+	 * cursor from that queue.
+	 */
+	DB_THREAD_LOCK(dbc->dbp);
+	TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
+	DB_THREAD_UNLOCK(dbc->dbp);
 
 	/* Discard the structures. */
-	FREE(cp, sizeof(CURSOR));
+	FREE(dbc->internal, sizeof(CURSOR));
 	FREE(dbc, sizeof(DBC));
 
-	PUTHANDLE(dbp);
 	return (ret);
 }
 
@@ -235,27 +260,22 @@ __bam_get(argdbp, txn, key, data, flags)
 	if ((ret = __db_getchk(argdbp, key, data, flags)) != 0)
 		return (ret);
 
-	/* Build a cursor. */
+	/* Build an internal cursor. */
 	memset(&cp, 0, sizeof(cp));
 	cp.dbc = &dbc;
 	cp.pgno = cp.dpgno = PGNO_INVALID;
 	cp.lock = LOCK_INVALID;
+	cp.flags = C_INTERNAL;
 
+	/* Build an external cursor. */
 	memset(&dbc, 0, sizeof(dbc));
 	dbc.dbp = argdbp;
 	dbc.txn = txn;
 	dbc.internal = &cp;
 
 	/* Get the key. */
-	if ((ret = __bam_c_get(&dbc,
-	    key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET)) != 0)
-		return (ret);
-
-	/* Discard any lock, the cursor didn't really exist. */
-	if (cp.lock != LOCK_INVALID)
-		(void)__BT_TLPUT(argdbp, cp.lock);
-
-	return (0);
+	return(__bam_c_get(&dbc,
+	    key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET));
 }
 
 /*
@@ -275,8 +295,7 @@ __bam_c_get(dbc, key, data, flags)
 	int exact, ret;
 
 	DEBUG_LREAD(dbc->dbp, dbc->txn, "bam_c_get",
-	    flags == DB_SET || flags == DB_SET_RANGE ? key : NULL,
-	    NULL, flags);
+	    flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);
 
 	cp = dbc->internal;
 
@@ -399,6 +418,10 @@ __bam_c_get(dbc, key, data, flags)
 	/* Release the pinned page. */
 	ret = memp_fput(dbp->mpf, cp->page, 0);
 
+	/* Internal cursors don't hold locks. */
+	if (F_ISSET(cp, C_INTERNAL) && cp->lock != LOCK_INVALID)
+		(void)__BT_TLPUT(dbp, cp->lock);
+
 	++t->lstat.bt_get;
 
 	if (0) {
@@ -864,7 +887,7 @@ __bam_c_prev(dbp, cp)
 	 * If at the beginning of the page, move to any previous one.
 	 *
 	 * !!!
-         * This code handles empty pages and pages with only deleted entries.
+	 * This code handles empty pages and pages with only deleted entries.
 	 */
 	for (;;) {
 		if (indx == 0) {
@@ -1472,8 +1495,7 @@ __bam_c_physdel(dbp, cp, h)
 		 *	empty the current page of duplicates, we don't need to
 		 *	touch the parent page.
 		 */
-		if (PREV_PGNO(h) != PGNO_INVALID ||
-		    (h != NULL && pgno == h->pgno))
+		if (prev_pgno != PGNO_INVALID || (h != NULL && pgno == h->pgno))
 			goto done;
 
 		/*
diff --git a/db2/btree/bt_put.c b/db2/btree/bt_put.c
index 0f0b1e7126..af09f76d41 100644
--- a/db2/btree/bt_put.c
+++ b/db2/btree/bt_put.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_put.c	10.24 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_put.c	10.25 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -99,7 +99,7 @@ __bam_put(argdbp, txn, key, data, flags)
 	t = dbp->internal;
 
 retry:	/*
-	 * Find the location at which to insert.  The call to bt_lookup()
+	 * Find the location at which to insert.  The call to __bam_lookup
 	 * leaves the returned page pinned.
 	 */
 	if ((ret = __bam_lookup(dbp, key, &exact)) != 0) {
diff --git a/db2/btree/bt_rec.c b/db2/btree/bt_rec.c
index 07a3d93c74..9aeb395f27 100644
--- a/db2/btree/bt_rec.c
+++ b/db2/btree/bt_rec.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_rec.c	10.13 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_rec.c	10.14 (Sleepycat) 9/6/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -298,11 +298,10 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
 			goto done;
 
 		/* Allocate and initialize new left/right child pages. */
-		if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL)
-			goto nomem;
-		if ((_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) {
-nomem:			__set_errno(ENOMEM);
-			__db_err(file_dbp->dbenv, "%s", strerror(errno));
+		if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL ||
+		    (_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) {
+			ret = ENOMEM;
+			__db_err(file_dbp->dbenv, "%s", strerror(ret));
 			goto out;
 		}
 		if (rootsplit) {
@@ -668,7 +667,7 @@ __bam_cadjust_recover(logp, dbtp, lsnp, redo, info)
 	REC_INTRO(__bam_cadjust_read);
 
 	if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) {
-		__set_errno(__db_pgerr(file_dbp, argp->pgno));
+		(void)__db_pgerr(file_dbp, argp->pgno);
 		pagep = NULL;
 		goto out;
 	}
diff --git a/db2/btree/bt_recno.c b/db2/btree/bt_recno.c
index 42ef9cc30d..f7c5cffdc6 100644
--- a/db2/btree/bt_recno.c
+++ b/db2/btree/bt_recno.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)bt_recno.c	10.15 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)bt_recno.c	10.19 (Sleepycat) 9/20/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -76,7 +76,7 @@ __ram_open(dbp, type, dbinfo)
 
 	/* Allocate and initialize the private RECNO structure. */
 	if ((rp = (RECNO *)calloc(1, sizeof(*rp))) == NULL)
-		return (errno);
+		return (ENOMEM);
 
 	if (dbinfo != NULL) {
 		/*
@@ -150,7 +150,7 @@ err:	/* If we mmap'd a source file, discard it. */
 
 	/* If we allocated room for key/data return, discard it. */
 	t = dbp->internal;
-	if (t->bt_rkey.data != NULL)
+	if (t != NULL && t->bt_rkey.data != NULL)
 		free(t->bt_rkey.data);
 
 	FREE(rp, sizeof(*rp));
@@ -193,7 +193,10 @@ __ram_cursor(dbp, txn, dbcp)
 	dbc->c_get = __ram_c_get;
 	dbc->c_put = __ram_c_put;
 
-	/* All cursor structures hang off the main DB structure. */
+	/*
+	 * All cursors are queued from the master DB structure.  Add the
+	 * cursor to that queue.
+	 */
 	DB_THREAD_LOCK(dbp);
 	TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links);
 	DB_THREAD_UNLOCK(dbp);
@@ -382,16 +385,29 @@ static int
 __ram_c_close(dbc)
 	DBC *dbc;
 {
-	DB *dbp;
-
 	DEBUG_LWRITE(dbc->dbp, dbc->txn, "ram_c_close", NULL, NULL, 0);
 
-	dbp = dbc->dbp;
+	return (__ram_c_iclose(dbc->dbp, dbc));
+}
 
-	/* Remove the cursor from the queue. */
-	DB_THREAD_LOCK(dbp);
-	TAILQ_REMOVE(&dbp->curs_queue, dbc, links);
-	DB_THREAD_UNLOCK(dbp);
+/*
+ * __ram_c_iclose --
+ *	Close a single cursor -- internal version.
+ *
+ * PUBLIC: int __ram_c_iclose __P((DB *, DBC *));
+ */
+int
+__ram_c_iclose(dbp, dbc)
+	DB *dbp;
+	DBC *dbc;
+{
+	/*
+	 * All cursors are queued from the master DB structure.  Remove the
+	 * cursor from that queue.
+	 */
+	DB_THREAD_LOCK(dbc->dbp);
+	TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
+	DB_THREAD_UNLOCK(dbc->dbp);
 
 	/* Discard the structures. */
 	FREE(dbc->internal, sizeof(RCURSOR));
diff --git a/db2/btree/btree.src b/db2/btree/btree.src
index 50cc0dd0ff..7c8c4b125f 100644
--- a/db2/btree/btree.src
+++ b/db2/btree/btree.src
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)btree.src	10.3 (Sleepycat) 8/17/97";
+static const char sccsid[] = "@(#)btree.src	10.4 (Sleepycat) 8/27/97";
 #endif /* not lint */
 
 PREFIX	bam
@@ -88,7 +88,7 @@ END
 
 /*
  * BTREE-adj: used to log the adjustment of an index.
- * 
+ *
  * pgno:	the page modified.
  * lsn:		the page's original lsn.
  * indx:	the index adjusted.
@@ -106,7 +106,7 @@ END
 
 /*
  * BTREE-cadjust: used to adjust the count change in an internal page.
- * 
+ *
  * pgno:	the page modified.
  * lsn:		the page's original lsn.
  * indx:	the index to be adjusted.
@@ -124,7 +124,7 @@ END
 
 /*
  * BTREE-cdel: used to log the intent-to-delete of a cursor record.
- * 
+ *
  * pgno:	the page modified.
  * lsn:		the page's original lsn.
  * indx:	the index to be deleted.
diff --git a/db2/btree/btree_auto.c b/db2/btree/btree_auto.c
index e6b72252e5..353ee7bc27 100644
--- a/db2/btree/btree_auto.c
+++ b/db2/btree/btree_auto.c
@@ -119,7 +119,7 @@ __bam_pg_alloc_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __bam_pg_alloc_read(dbtp->data, &argp)) != 0)
+	if ((ret = __bam_pg_alloc_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]bam_pg_alloc: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -284,7 +284,7 @@ __bam_pg_free_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __bam_pg_free_read(dbtp->data, &argp)) != 0)
+	if ((ret = __bam_pg_free_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]bam_pg_free: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -479,7 +479,7 @@ __bam_split_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __bam_split_read(dbtp->data, &argp)) != 0)
+	if ((ret = __bam_split_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]bam_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -672,7 +672,7 @@ __bam_rsplit_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __bam_rsplit_read(dbtp->data, &argp)) != 0)
+	if ((ret = __bam_rsplit_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]bam_rsplit: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -848,7 +848,7 @@ __bam_adj_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __bam_adj_read(dbtp->data, &argp)) != 0)
+	if ((ret = __bam_adj_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]bam_adj: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -1007,7 +1007,7 @@ __bam_cadjust_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __bam_cadjust_read(dbtp->data, &argp)) != 0)
+	if ((ret = __bam_cadjust_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]bam_cadjust: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -1157,7 +1157,7 @@ __bam_cdel_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __bam_cdel_read(dbtp->data, &argp)) != 0)
+	if ((ret = __bam_cdel_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]bam_cdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
diff --git a/db2/clib/getlong.c b/db2/clib/getlong.c
index 0cc8567081..85f4e8c9e2 100644
--- a/db2/clib/getlong.c
+++ b/db2/clib/getlong.c
@@ -18,7 +18,6 @@ static const char sccsid[] = "@(#)getlong.c	10.2 (Sleepycat) 5/1/97";
 #endif
 
 #include "db.h"
-#include "db_int.h"
 #include "clib_ext.h"
 
 /*
diff --git a/db2/db.h b/db2/db.h
index c80d8e3633..6911002ed5 100644
--- a/db2/db.h
+++ b/db2/db.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db.h.src	10.71 (Sleepycat) 9/4/97
+ *	@(#)db.h.src	10.77 (Sleepycat) 9/24/97
  */
 
 #ifndef _DB_H_
@@ -67,8 +67,8 @@
 
 #define	DB_VERSION_MAJOR	2
 #define	DB_VERSION_MINOR	3
-#define	DB_VERSION_PATCH	6
-#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.6: (9/4/97)"
+#define	DB_VERSION_PATCH	10
+#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.10: (9/24/97)"
 
 typedef	u_int32_t	db_pgno_t;	/* Page number type. */
 typedef	u_int16_t	db_indx_t;	/* Page offset type. */
@@ -339,7 +339,7 @@ struct __db_ilock {			/* Internal DB access method lock. */
 
 /* DB access method description structure. */
 struct __db {
-	void	*mutex;			/* Synchronization for free threading */
+	void	*mutexp;		/* Synchronization for free threading */
 	DBTYPE	 type;			/* DB access method. */
 	DB_ENV	*dbenv;			/* DB_ENV structure. */
 	DB_ENV	*mp_dbenv;		/* DB_ENV for local mpool creation. */
@@ -641,11 +641,11 @@ extern "C" {
 #endif
 int	memp_close __P((DB_MPOOL *));
 int	memp_fclose __P((DB_MPOOLFILE *));
-int	memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, unsigned long, void *));
+int	memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, int, void *));
 int	memp_fopen __P((DB_MPOOL *, const char *,
 	    int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **));
-int	memp_fput __P((DB_MPOOLFILE *, void *, unsigned long));
-int	memp_fset __P((DB_MPOOLFILE *, void *, unsigned long));
+int	memp_fput __P((DB_MPOOLFILE *, void *, int));
+int	memp_fset __P((DB_MPOOLFILE *, void *, int));
 int	memp_fsync __P((DB_MPOOLFILE *));
 int	memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **));
 int	memp_register __P((DB_MPOOL *, int,
@@ -698,7 +698,7 @@ extern "C" {
 #endif
 int	  txn_abort __P((DB_TXN *));
 int	  txn_begin __P((DB_TXNMGR *, DB_TXN *, DB_TXN **));
-int	  txn_checkpoint __P((const DB_TXNMGR *, long, long));
+int	  txn_checkpoint __P((const DB_TXNMGR *, int, int));
 int	  txn_commit __P((DB_TXN *));
 int	  txn_close __P((DB_TXNMGR *));
 u_int32_t txn_id __P((DB_TXN *));
diff --git a/db2/db/db.c b/db2/db/db.c
index 8dad5febe8..9ebe73cf6e 100644
--- a/db2/db/db.c
+++ b/db2/db/db.c
@@ -44,7 +44,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db.c	10.38 (Sleepycat) 9/2/97";
+static const char sccsid[] = "@(#)db.c	10.41 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -137,7 +137,13 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
 	}
 	dbp->dbenv = dbenv;
 
-	/* Convert the dbinfo flags. */
+	/* Convert the db_open(3) flags. */
+	if (LF_ISSET(DB_RDONLY))
+		F_SET(dbp, DB_AM_RDONLY);
+	if (LF_ISSET(DB_THREAD))
+		F_SET(dbp, DB_AM_THREAD);
+
+	/* Convert the dbinfo structure flags. */
 	if (dbinfo != NULL) {
 		/*
 		 * !!!
@@ -160,23 +166,6 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
 			F_SET(dbp, DB_RE_SNAPSHOT);
 	}
 
-	/* Set based on the open(2) flags. */
-	if (LF_ISSET(DB_RDONLY))
-		F_SET(dbp, DB_AM_RDONLY);
-
-	/* Check threading fields. */
-	if (LF_ISSET(DB_THREAD)) {
-		if ((dbp->mutex =
-		    (db_mutex_t *)malloc(sizeof(db_mutex_t))) == NULL) {
-			__db_err(dbenv, "%s", strerror(ENOMEM));
-			ret = ENOMEM;
-			goto err;
-		}
-		__db_mutex_init(dbp->mutex, 0);
-
-		F_SET(dbp, DB_AM_THREAD);
-	}
-
 	/*
 	 * Always set the master and initialize the queues, so we can
 	 * use these fields without checking the thread bit.
@@ -190,7 +179,7 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
 	 * Set based on the dbenv fields, although no logging or transactions
 	 * are possible for temporary files.
 	 */
-	if (dbp->dbenv != NULL) {
+	if (dbenv != NULL) {
 		if (dbenv->lk_info != NULL)
 			F_SET(dbp, DB_AM_LOCKING);
 		if (fname != NULL && dbenv->lg_info != NULL)
@@ -274,8 +263,8 @@ open_retry:	if (LF_ISSET(DB_CREATE)) {
 		 * sizes, we limit the default pagesize to 16K.
 		 */
 		if (dbp->pgsize == 0) {
-			if ((ret = __db_stat(dbp->dbenv,
-			    real_name, fd, NULL, &io)) != 0)
+			if ((ret =
+			    __db_stat(dbenv, real_name, fd, NULL, &io)) != 0)
 				goto err;
 			if (io < 512)
 				io = 512;
@@ -573,6 +562,15 @@ empty:	/*
 	    0, &pgcookie, dbp->lock.fileid, &dbp->mpf)) != 0)
 		goto err;
 
+	/*
+	 * XXX
+	 * Truly spectacular layering violation.  We need a per-thread mutex
+	 * that lives in shared memory (thanks, HP-UX!) and so we acquire a
+	 * pointer to the mpool one.
+	 */
+	if (F_ISSET(dbp, DB_AM_THREAD))
+		dbp->mutexp = dbp->mpf->mutexp;
+
 	/* Get a log file id. */
 	if (F_ISSET(dbp, DB_AM_LOGGING) &&
 	    (ret = log_register(dbenv->lg_info,
@@ -672,7 +670,9 @@ db_close(dbp, flags)
 	DB *tdbp;
 	int ret, t_ret;
 
-	ret = 0;
+	/* Validate arguments. */
+	if ((ret = __db_fchk(dbp->dbenv, "db_close", flags, DB_NOSYNC)) != 0)
+		return (ret);
 
 	/* Sync the underlying file. */
 	if (!LF_ISSET(DB_NOSYNC) &&
@@ -685,10 +685,26 @@ db_close(dbp, flags)
 	 */
 	for (tdbp = LIST_FIRST(&dbp->handleq);
 	    tdbp != NULL; tdbp = LIST_NEXT(tdbp, links)) {
-
 		while ((dbc = TAILQ_FIRST(&tdbp->curs_queue)) != NULL)
-			if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
-				ret = t_ret;
+			switch (tdbp->type) {
+			case DB_BTREE:
+				if ((t_ret =
+				    __bam_c_iclose(tdbp, dbc)) != 0 && ret == 0)
+					ret = t_ret;
+				break;
+			case DB_HASH:
+				if ((t_ret =
+				    __ham_c_iclose(tdbp, dbc)) != 0 && ret == 0)
+					ret = t_ret;
+				break;
+			case DB_RECNO:
+				if ((t_ret =
+				    __ram_c_iclose(tdbp, dbc)) != 0 && ret == 0)
+					ret = t_ret;
+				break;
+			default:
+				abort();
+			}
 
 		switch (tdbp->type) {
 		case DB_BTREE:
@@ -706,7 +722,6 @@ db_close(dbp, flags)
 		default:
 			abort();
 		}
-
 	}
 
 	/* Sync the memory pool. */
@@ -722,10 +737,6 @@ db_close(dbp, flags)
 	    (t_ret = memp_close(dbp->mp)) != 0 && ret == 0)
 		ret = t_ret;
 
-	/* Discard the mutex. */
-	if (dbp->mutex != NULL)
-		FREE(dbp->mutex, sizeof(db_mutex_t));
-
 	/* Discard the log file id. */
 	if (F_ISSET(dbp, DB_AM_LOGGING))
 		(void)log_unregister(dbp->dbenv->lg_info, dbp->log_fileid);
diff --git a/db2/db/db_auto.c b/db2/db/db_auto.c
index 4684f1a39f..6922504383 100644
--- a/db2/db/db_auto.c
+++ b/db2/db/db_auto.c
@@ -141,7 +141,7 @@ __db_addrem_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_addrem_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_addrem_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_addrem: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -331,7 +331,7 @@ __db_split_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_split_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_split_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_split: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -526,7 +526,7 @@ __db_big_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_big_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_big_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_big: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -693,7 +693,7 @@ __db_ovref_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_ovref_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_ovref_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_ovref: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -854,7 +854,7 @@ __db_relink_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_relink_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_relink_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_relink: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -1017,7 +1017,7 @@ __db_addpage_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_addpage_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_addpage_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_addpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -1192,7 +1192,7 @@ __db_debug_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_debug_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_debug_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_debug: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -1347,7 +1347,7 @@ __db_noop_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __db_noop_read(dbtp->data, &argp)) != 0)
+	if ((ret = __db_noop_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]db_noop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
diff --git a/db2/db/db_conv.c b/db2/db/db_conv.c
index 6608005b66..8eccc2e602 100644
--- a/db2/db/db_conv.c
+++ b/db2/db/db_conv.c
@@ -44,7 +44,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_conv.c	10.5 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)db_conv.c	10.7 (Sleepycat) 9/21/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -58,28 +58,34 @@ static const char sccsid[] = "@(#)db_conv.c	10.5 (Sleepycat) 9/3/97";
 #include "db_swap.h"
 #include "db_am.h"
 
-static int __db_convert __P((db_pgno_t, void *, int));
+static int __db_convert __P((db_pgno_t, void *, size_t, int));
 
 /*
- * __db_pgin, __db_pgout --
+ * __db_pgin --
  *
- * PUBLIC: int __db_pgin __P((db_pgno_t, void *));
- * PUBLIC: int __db_pgout __P((db_pgno_t, void *));
+ * PUBLIC: int __db_pgin __P((db_pgno_t, size_t, void *));
  */
 int
-__db_pgin(pg, pp)
+__db_pgin(pg, pagesize, pp)
 	db_pgno_t pg;
+	size_t pagesize;
 	void *pp;
 {
-	return (__db_convert(pg, pp, 1));
+	return (__db_convert(pg, pp, pagesize, 1));
 }
 
+/*
+ * __db_pgout --
+ *
+ * PUBLIC: int __db_pgout __P((db_pgno_t, size_t, void *));
+ */
 int
-__db_pgout(pg, pp)
+__db_pgout(pg, pagesize, pp)
 	db_pgno_t pg;
+	size_t pagesize;
 	void *pp;
 {
-	return (__db_convert(pg, pp, 0));
+	return (__db_convert(pg, pp, pagesize, 0));
 }
 
 /*
@@ -87,19 +93,19 @@ __db_pgout(pg, pp)
  *	Actually convert a page.
  */
 static int
-__db_convert(pg, pp, pgin)
+__db_convert(pg, pp, pagesize, pgin)
 	db_pgno_t pg;			/* Unused, but left for the future. */
 	void *pp;
+	size_t pagesize;
 	int pgin;
 {
 	BINTERNAL *bi;
 	BKEYDATA *bk;
 	BOVERFLOW *bo;
-	HKEYDATA *hk;
 	PAGE *h;
 	RINTERNAL *ri;
-	db_indx_t i;
-	u_int8_t *p;
+	db_indx_t i, len, tmp;
+	u_int8_t *p, *end;
 
 	h = pp;
 	if (pgin) {
@@ -118,24 +124,42 @@ __db_convert(pg, pp, pgin)
 			if (pgin)
 				M_16_SWAP(h->inp[i]);
 
-			hk = GET_HKEYDATA(h, i);
-			switch (hk->type) {
+			switch (HPAGE_TYPE(h, i)) {
 			case H_KEYDATA:
 				break;
 			case H_DUPLICATE:
+				len = LEN_HKEYDATA(h, pagesize, i);
+				p = HKEYDATA_DATA(P_ENTRY(h, i));
+				for (end = p + len; p < end;) {
+					if (pgin) {
+						P_16_SWAP(p);
+						memcpy(&tmp,
+						    p, sizeof(db_indx_t));
+						p += sizeof(db_indx_t);
+					} else {
+						memcpy(&tmp,
+						    p, sizeof(db_indx_t));
+						SWAP16(p);
+					}
+					p += tmp;
+					SWAP16(p);
+				}
+				break;
+			case H_OFFDUP:
+				p = HOFFPAGE_PGNO(P_ENTRY(h, i));
+				SWAP32(p);			/* pgno */
+				break;
 			case H_OFFPAGE:
-				p = (u_int8_t *)hk + sizeof(u_int8_t);
-				++p;
-				SWAP32(p);			/* tlen */
+				p = HOFFPAGE_PGNO(P_ENTRY(h, i));
 				SWAP32(p);			/* pgno */
-				SWAP16(p);			/* offset */
-				SWAP16(p);			/* len */
+				SWAP32(p);			/* tlen */
 				break;
 			}
 
-			if (!pgin)
-				M_16_SWAP(h->inp[i]);
 		}
+		if (!pgin)
+			for (i = 0; i < NUM_ENT(h); i++)
+				M_16_SWAP(h->inp[i]);
 		break;
 	case P_LBTREE:
 	case P_LRECNO:
diff --git a/db2/db/db_pr.c b/db2/db/db_pr.c
index f86fd6770a..09d8057da4 100644
--- a/db2/db/db_pr.c
+++ b/db2/db/db_pr.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_pr.c	10.16 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)db_pr.c	10.17 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -184,7 +184,7 @@ __db_prbtree(dbp)
 	BTMETA *mp;
 	BTREE *t;
 	DB_LOCK lock;
-	EPG *sp;
+	EPG *epg;
 	FILE *fp;
 	RECNO *rp;
 	db_pgno_t i;
@@ -230,8 +230,8 @@ __db_prbtree(dbp)
 		    (u_long)rp->re_emap, (u_long)rp->re_msize);
 	}
 	(void)fprintf(fp, "stack:");
-	for (sp = t->bt_stack; sp < t->bt_sp; ++sp)
-		(void)fprintf(fp, " %lu", (u_long)sp->page->pgno);
+	for (epg = t->bt_stack; epg < t->bt_sp; ++epg)
+		(void)fprintf(fp, " %lu", (u_long)epg->page->pgno);
 	(void)fprintf(fp, "\n");
 	(void)fprintf(fp, "ovflsize: %lu\n", (u_long)t->bt_ovflsize);
 	(void)fflush(fp);
@@ -367,20 +367,15 @@ __db_prpage(h, all)
 {
 	BINTERNAL *bi;
 	BKEYDATA *bk;
-	HKEYDATA *hkd;
 	HOFFPAGE a_hkd;
 	FILE *fp;
 	RINTERNAL *ri;
 	db_indx_t dlen, len, i;
 	db_pgno_t pgno;
-	u_int8_t *p;
 	int deleted, ret;
 	const char *s;
-
-	bi = NULL;				/* XXX: Shut the compiler up. */
-	bk = NULL;
-	hkd = NULL;
-	ri = NULL;
+	u_int8_t *ep, *hk, *p;
+	void *sp;
 
 	fp = __db_prinit(NULL);
 
@@ -450,22 +445,18 @@ __db_prpage(h, all)
 		deleted = 0;
 		switch (TYPE(h)) {
 		case P_HASH:
-			hkd = GET_HKEYDATA(h, i);
-			break;
 		case P_IBTREE:
-			bi = GET_BINTERNAL(h, i);
-			break;
 		case P_IRECNO:
-			ri = GET_RINTERNAL(h, i);
+			sp = P_ENTRY(h, i);
 			break;
 		case P_LBTREE:
-			bk = GET_BKEYDATA(h, i);
+			sp = P_ENTRY(h, i);
 			deleted = i % 2 == 0 &&
 			    B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type);
 			break;
 		case P_LRECNO:
 		case P_DUPLICATE:
-			bk = GET_BKEYDATA(h, i);
+			sp = P_ENTRY(h, i);
 			deleted = B_DISSET(GET_BKEYDATA(h, i)->type);
 			break;
 		default:
@@ -478,11 +469,11 @@ __db_prpage(h, all)
 		    deleted ? "D" : " ", (u_long)i, (u_long)h->inp[i]);
 		switch (TYPE(h)) {
 		case P_HASH:
-			switch (hkd->type) {
+			hk = sp;
+			switch (HPAGE_PTYPE(hk)) {
 			case H_OFFDUP:
 				memcpy(&pgno,
-				    (u_int8_t *)hkd + SSZ(HOFFDUP, pgno),
-				    sizeof(db_pgno_t));
+				    HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
 				fprintf(fp,
 				    "%4lu [offpage dups]\n", (u_long)pgno);
 				break;
@@ -499,7 +490,8 @@ __db_prpage(h, all)
 					len = 1;
 
 				fprintf(fp, "Duplicates:\n");
-				for (p = hkd->data; p < hkd->data + len;) {
+				for (p = HKEYDATA_DATA(hk),
+				    ep = p + len; p < ep;) {
 					memcpy(&dlen, p, sizeof(db_indx_t));
 					p += sizeof(db_indx_t);
 					fprintf(fp, "\t\t");
@@ -509,13 +501,13 @@ __db_prpage(h, all)
 				break;
 			case H_KEYDATA:
 				if (i != 0)
-					__db_pr(hkd->data,
+					__db_pr(HKEYDATA_DATA(hk),
 					    LEN_HKEYDATA(h, 0, i));
 				else
-					fprintf(fp, "%s\n", hkd->data);
+					fprintf(fp, "%s\n", HKEYDATA_DATA(hk));
 				break;
 			case H_OFFPAGE:
-				memcpy(&a_hkd, hkd, HOFFPAGE_SIZE);
+				memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
 				fprintf(fp,
 				    "overflow: total len: %4lu page: %4lu\n",
 				    (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
@@ -523,6 +515,7 @@ __db_prpage(h, all)
 			}
 			break;
 		case P_IBTREE:
+			bi = sp;
 			fprintf(fp, "count: %4lu pgno: %4lu ",
 			    (u_long)bi->nrecs, (u_long)bi->pgno);
 			switch (B_TYPE(bi->type)) {
@@ -541,12 +534,14 @@ __db_prpage(h, all)
 			}
 			break;
 		case P_IRECNO:
+			ri = sp;
 			fprintf(fp, "entries %4lu pgno %4lu\n",
 			    (u_long)ri->nrecs, (u_long)ri->pgno);
 			break;
 		case P_LBTREE:
 		case P_LRECNO:
 		case P_DUPLICATE:
+			bk = sp;
 			switch (B_TYPE(bk->type)) {
 			case B_KEYDATA:
 				__db_pr(bk->data, bk->len);
@@ -582,13 +577,9 @@ __db_isbad(h, die)
 {
 	BINTERNAL *bi;
 	BKEYDATA *bk;
-	HKEYDATA *hkd;
 	FILE *fp;
 	db_indx_t i;
-
-	bi = NULL;				/* XXX: Shut the compiler up. */
-	bk = NULL;
-	hkd = NULL;
+	int type;
 
 	fp = __db_prinit(NULL);
 
@@ -618,13 +609,13 @@ __db_isbad(h, die)
 		}
 		switch (TYPE(h)) {
 		case P_HASH:
-			hkd = GET_HKEYDATA(h, i);
-			if (hkd->type != H_OFFDUP &&
-			    hkd->type != H_DUPLICATE &&
-			    hkd->type != H_KEYDATA &&
-			    hkd->type != H_OFFPAGE) {
+			type = HPAGE_TYPE(h, i);
+			if (type != H_OFFDUP &&
+			    type != H_DUPLICATE &&
+			    type != H_KEYDATA &&
+			    type != H_OFFPAGE) {
 				fprintf(fp, "ILLEGAL HASH TYPE: %lu\n",
-				    (u_long)hkd->type);
+				    (u_long)type);
 				goto bad;
 			}
 			break;
diff --git a/db2/db/db_ret.c b/db2/db/db_ret.c
index baf0665446..ee2bc82f87 100644
--- a/db2/db/db_ret.c
+++ b/db2/db/db_ret.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_ret.c	10.6 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)db_ret.c	10.7 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -46,18 +46,19 @@ __db_ret(dbp, h, indx, dbt, memp, memsize)
 	HOFFPAGE ho;
 	BOVERFLOW *bo;
 	u_int32_t len;
-	void *data, *hk;
+	u_int8_t *hk;
+	void *data;
 
 	switch (TYPE(h)) {
 	case P_HASH:
 		hk = P_ENTRY(h, indx);
-		if (((HKEYDATA *)hk)->type == H_OFFPAGE) {
+		if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
 			memcpy(&ho, hk, sizeof(HOFFPAGE));
 			return (__db_goff(dbp, dbt,
 			    ho.tlen, ho.pgno, memp, memsize));
 		}
 		len = LEN_HKEYDATA(h, dbp->pgsize, indx);
-		data = ((HKEYDATA *)hk)->data;
+		data = HKEYDATA_DATA(hk);
 		break;
 	case P_DUPLICATE:
 	case P_LBTREE:
diff --git a/db2/db/db_thread.c b/db2/db/db_thread.c
index e956e809d9..170baf5345 100644
--- a/db2/db/db_thread.c
+++ b/db2/db/db_thread.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_thread.c	8.11 (Sleepycat) 8/18/97";
+static const char sccsid[] = "@(#)db_thread.c	8.12 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -42,7 +42,7 @@ __db_gethandle(dbp, am_func, dbpp)
 	DB *ret_dbp;
 	int ret, t_ret;
 
-	if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutex, -1,
+	if ((ret = __db_mutex_lock((db_mutex_t *)dbp->mutexp, -1,
 	    dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
 		return (ret);
 
@@ -75,7 +75,7 @@ err:		if (ret_dbp != NULL)
 			FREE(ret_dbp, sizeof(*ret_dbp));
 	}
 	if ((t_ret =
-	    __db_mutex_unlock((db_mutex_t *)dbp->mutex, -1)) != 0 && ret == 0)
+	    __db_mutex_unlock((db_mutex_t *)dbp->mutexp, -1)) != 0 && ret == 0)
 		ret = t_ret;
 	return (ret);
 }
@@ -94,13 +94,13 @@ __db_puthandle(dbp)
 	int ret;
 
 	master = dbp->master;
-	if ((ret = __db_mutex_lock((db_mutex_t *)master->mutex, -1,
+	if ((ret = __db_mutex_lock((db_mutex_t *)master->mutexp, -1,
 	    dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
 		return (ret);
 
 	LIST_INSERT_HEAD(&master->handleq, dbp, links);
 
-	return (__db_mutex_unlock((db_mutex_t *)master->mutex, -1));
+	return (__db_mutex_unlock((db_mutex_t *)master->mutexp, -1));
 }
 
 /*
diff --git a/db2/db_185.h b/db2/db_185.h
index 650d365a60..b6a4d0a12a 100644
--- a/db2/db_185.h
+++ b/db2/db_185.h
@@ -36,7 +36,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)db_185.h.src	8.3 (Sleepycat) 7/27/97
+ *	@(#)db_185.h.src	8.4 (Sleepycat) 9/16/97
  */
 
 #ifndef _DB_185_H_
@@ -72,6 +72,14 @@
 
 #endif
 
+/*
+ * XXX
+ * SGI/IRIX already has a pgno_t.
+ */
+#ifdef sgi
+#define        pgno_t  db_pgno_t
+#endif
+
 #define	MAX_PAGE_NUMBER	0xffffffff	/* >= # of pages in a file */
 typedef u_int32_t	pgno_t;
 #define	MAX_PAGE_OFFSET	65535		/* >= # of bytes in a page */
diff --git a/db2/db_int.h b/db2/db_int.h
index a088c693a8..56dfddb73f 100644
--- a/db2/db_int.h
+++ b/db2/db_int.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_int.h.src	10.28 (Sleepycat) 8/20/97
+ *	@(#)db_int.h.src	10.30 (Sleepycat) 9/23/97
  */
 
 #ifndef _DB_INTERNAL_H_
@@ -25,12 +25,6 @@
 
 #define	DB_MINCACHE	10		/* Minimum cached pages */
 
-/* Handle `errno' in the presence of multi-threading correctly.  On some
-   systems we need a special macro to do this right.  */
-#ifndef __set_errno
-# define __set_errno(val) (errno) = (val)
-#endif
-
 /*
  * Aligning items to particular sizes or in pages or memory.  ALIGNP is a
  * separate macro, as we've had to cast the pointer to different integral
@@ -94,7 +88,7 @@
 
 /* Structure used to print flag values. */
 typedef struct __fn {
-	u_int32_t mask;			/* Flag value. */
+	u_int32_t   mask;		/* Flag value. */
 	const char *name;		/* Flag name. */
 } FN;
 
@@ -183,11 +177,11 @@ typedef struct _db_mutex_t {
 /* Lock/unlock a DB thread. */
 #define	DB_THREAD_LOCK(dbp)						\
 	(F_ISSET(dbp, DB_AM_THREAD) ?					\
-	    __db_mutex_lock((db_mutex_t *)(dbp)->mutex,  -1,		\
+	    __db_mutex_lock((db_mutex_t *)(dbp)->mutexp,  -1,		\
 	        (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
 #define	DB_THREAD_UNLOCK(dbp)						\
 	(F_ISSET(dbp, DB_AM_THREAD) ?					\
-	    __db_mutex_unlock((db_mutex_t *)(dbp)->mutex,  -1) : 0)
+	    __db_mutex_unlock((db_mutex_t *)(dbp)->mutexp,  -1) : 0)
 
 /* Btree/recno local statistics structure. */
 struct __db_bt_lstat;	typedef struct __db_bt_lstat DB_BTREE_LSTAT;
@@ -312,14 +306,6 @@ typedef struct __dbpginfo {
  * Transactions and recovery.
  *******************************************************/
 /*
- * The locker id space is divided between the transaction manager and the lock
- * manager.  Lockid's start at 0 and go to MAX_LOCKER_ID.  Txn Id's start at
- * MAX_LOCKER_ID + 1 and go up to MAX_TXNID.
- */
-#define	MAX_LOCKER_ID	0x0fffffff
-#define	MAX_TXNID	0xffffffff
-
-/*
  * Out of band value for a lock.  The locks are returned to callers as offsets
  * into the lock regions.  Since the RLAYOUT structure begins all regions, an
  * offset of 0 is guaranteed not to be a valid lock.
diff --git a/db2/hash/hash.c b/db2/hash/hash.c
index 6d8c40057d..d986e08087 100644
--- a/db2/hash/hash.c
+++ b/db2/hash/hash.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash.c	10.25 (Sleepycat) 8/24/97";
+static const char sccsid[] = "@(#)hash.c	10.27 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -573,8 +573,6 @@ __ham_c_close(cursor)
 	DBC *cursor;
 {
 	DB  *ldbp;
-	HTAB *hashp;
-	HASH_CURSOR *hcp;
 	int ret;
 
 	DEBUG_LWRITE(cursor->dbp, cursor->txn, "ham_c_close", NULL, NULL, 0);
@@ -590,8 +588,32 @@ __ham_c_close(cursor)
 	if (F_ISSET(cursor->dbp, DB_AM_THREAD) &&
 	    (ret = __db_gethandle(cursor->dbp, __ham_hdup, &ldbp)) != 0)
 		return (ret);
-	hashp = (HTAB *)ldbp->internal;
-	hcp = (HASH_CURSOR *)cursor->internal;
+
+	ret = __ham_c_iclose(ldbp, cursor);
+
+	if (F_ISSET(ldbp, DB_AM_THREAD))
+		__db_puthandle(ldbp);
+	return (ret);
+}
+/*
+ * __ham_c_iclose --
+ *
+ * Internal cursor close routine; assumes it is being passed the correct
+ * handle, rather than getting and putting a handle.
+ *
+ * PUBLIC: int __ham_c_iclose __P((DB *, DBC *));
+ */
+int
+__ham_c_iclose(dbp, dbc)
+	DB *dbp;
+	DBC *dbc;
+{
+	HASH_CURSOR *hcp;
+	HTAB *hashp;
+	int ret;
+
+	hashp = (HTAB *)dbp->internal;
+	hcp = (HASH_CURSOR *)dbc->internal;
 	ret = __ham_item_done(hashp, hcp, 0);
 
 	if (hcp->big_key)
@@ -602,19 +624,16 @@ __ham_c_close(cursor)
 	/*
 	 * All cursors (except the default ones) are linked off the master.
 	 * Therefore, when we close the cursor, we have to remove it from
-	 * the master, not the local one.  When we are closing the file in
-	 * its entirety, then we clear the THREAD bit and the master and
-	 * local are identical, so we remove the correct one.
+	 * the master, not the local one.
+	 * XXX I am always removing from the master; what about local cursors?
 	 */
-	DB_THREAD_LOCK(cursor->dbp);
-	TAILQ_REMOVE(&cursor->dbp->curs_queue, cursor, links);
-	DB_THREAD_UNLOCK(cursor->dbp);
-
-	if (F_ISSET(cursor->dbp, DB_AM_THREAD))
-		__db_puthandle(ldbp);
+	DB_THREAD_LOCK(dbc->dbp);
+	TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
+	DB_THREAD_UNLOCK(dbc->dbp);
 
 	FREE(hcp, sizeof(HASH_CURSOR));
-	FREE(cursor, sizeof(DBC));
+	FREE(dbc, sizeof(DBC));
+
 	return (ret);
 }
 
@@ -695,10 +714,9 @@ __ham_c_del(cursor, flags)
 			hcp->dndx = 0;				/* Case 2 */
 			hcp->dpgno = PGNO(hcp->dpagep);
 			if (ppgno == PGNO_INVALID)
-				memcpy(P_ENTRY(hcp->pagep,
-				    H_DATAINDEX(hcp->bndx)) +
-				    SSZ(HOFFDUP, pgno), &hcp->dpgno,
-				    sizeof(db_pgno_t));
+				memcpy(HOFFDUP_PGNO(P_ENTRY(hcp->pagep,
+				    H_DATAINDEX(hcp->bndx))),
+				    &hcp->dpgno, sizeof(db_pgno_t));
 			F_SET(hcp, H_DELETED);
 		} else					/* Case 1 */
 			F_SET(hcp, H_DELETED);
@@ -1051,18 +1069,17 @@ __ham_dup_return(hashp, hcp, val, flags)
 	DBT *val;
 	int flags;
 {
-	HKEYDATA *hk;
 	PAGE *pp;
 	DBT *myval, tmp_val;
 	db_indx_t ndx;
 	db_pgno_t pgno;
-	u_int8_t type;
+	u_int8_t *hk, type;
 	int indx, ret;
 	db_indx_t len;
 
 	/* Check for duplicate and return the first one. */
 	ndx = H_DATAINDEX(hcp->bndx);
-	type = GET_HKEYDATA(hcp->pagep, ndx)->type;
+	type = HPAGE_TYPE(hcp->pagep, ndx);
 	pp = hcp->pagep;
 	myval = val;
 
@@ -1088,7 +1105,8 @@ __ham_dup_return(hashp, hcp, val, flags)
 				hcp->dndx = 0;
 				hcp->dup_off = 0;
 				do {
-					memcpy(&len, hk->data + hcp->dup_off,
+					memcpy(&len,
+					    HKEYDATA_DATA(hk) + hcp->dup_off,
 					    sizeof(db_indx_t));
 					hcp->dup_off += DUP_SIZE(len);
 					hcp->dndx++;
@@ -1096,15 +1114,15 @@ __ham_dup_return(hashp, hcp, val, flags)
 				hcp->dup_off -= DUP_SIZE(len);
 				hcp->dndx--;
 			} else {
-				memcpy(&len, hk->data, sizeof(db_indx_t));
+				memcpy(&len,
+				    HKEYDATA_DATA(hk), sizeof(db_indx_t));
 				hcp->dup_off = 0;
 				hcp->dndx = 0;
 			}
 			hcp->dup_len = len;
 		} else if (type == H_OFFDUP) {
 			F_SET(hcp, H_ISDUP);
-			memcpy(&pgno,
-			    P_ENTRY(hcp->pagep, ndx) + SSZ(HOFFDUP, pgno),
+			memcpy(&pgno, HOFFDUP_PGNO(P_ENTRY(hcp->pagep, ndx)),
 			    sizeof(db_pgno_t));
 			if (flags == DB_LAST || flags == DB_PREV) {
 				indx = (int)hcp->dndx;
@@ -1166,7 +1184,7 @@ __ham_overwrite(hashp, hcp, nval)
 	DBT *nval;
 {
 	DBT *myval, tmp_val;
-	HKEYDATA *hk;
+	u_int8_t *hk;
 
 	if (F_ISSET(hashp->dbp, DB_AM_DUP))
 		return (__ham_add_dup(hashp, hcp, nval, DB_KEYLAST));
@@ -1176,10 +1194,9 @@ __ham_overwrite(hashp, hcp, nval)
 		F_SET(&tmp_val, DB_DBT_PARTIAL);
 		tmp_val.doff = 0;
 		hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
-		if (hk->type == H_OFFPAGE)
+		if (HPAGE_PTYPE(hk) == H_OFFPAGE)
 			memcpy(&tmp_val.dlen,
-			    (u_int8_t *)hk + SSZ(HOFFPAGE, tlen),
-			    sizeof(u_int32_t));
+			    HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
 		else
 			tmp_val.dlen = LEN_HDATA(hcp->pagep,
 			    hashp->hdr->pagesize,hcp->bndx);
@@ -1207,10 +1224,10 @@ __ham_lookup(hashp, hcp, key, sought, mode)
 	u_int32_t sought;
 	db_lockmode_t mode;
 {
-	HKEYDATA *hk;
 	db_pgno_t pgno;
 	u_int32_t tlen;
 	int match, ret, t_ret;
+	u_int8_t *hk;
 
 	/*
 	 * Set up cursor so that we're looking for space to add an item
@@ -1229,14 +1246,12 @@ __ham_lookup(hashp, hcp, key, sought, mode)
 			break;
 
 		hk = H_PAIRKEY(hcp->pagep, hcp->bndx);
-		switch (hk->type) {
+		switch (HPAGE_PTYPE(hk)) {
 		case H_OFFPAGE:
-			memcpy(&tlen, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen),
-			    sizeof(u_int32_t));
+			memcpy(&tlen, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
 			if (tlen == key->size) {
 				memcpy(&pgno,
-				    (u_int8_t *)hk + SSZ(HOFFPAGE, pgno),
-				    sizeof(db_pgno_t));
+				    HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));
 				match = __db_moff(hashp->dbp, key, pgno);
 				if (match == 0) {
 					F_SET(hcp, H_OK);
@@ -1247,7 +1262,8 @@ __ham_lookup(hashp, hcp, key, sought, mode)
 		case H_KEYDATA:
 			if (key->size == LEN_HKEY(hcp->pagep,
 			    hashp->hdr->pagesize, hcp->bndx) &&
-			    memcmp(key->data, hk->data, key->size) == 0) {
+			    memcmp(key->data,
+			    HKEYDATA_DATA(hk), key->size) == 0) {
 				F_SET(hcp, H_OK);
 				return (0);
 			}
diff --git a/db2/hash/hash_auto.c b/db2/hash/hash_auto.c
index f8ab80c8ee..2279de9668 100644
--- a/db2/hash/hash_auto.c
+++ b/db2/hash/hash_auto.c
@@ -138,7 +138,7 @@ __ham_insdel_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __ham_insdel_read(dbtp->data, &argp)) != 0)
+	if ((ret = __ham_insdel_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]ham_insdel: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -335,7 +335,7 @@ __ham_newpage_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __ham_newpage_read(dbtp->data, &argp)) != 0)
+	if ((ret = __ham_newpage_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]ham_newpage: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -498,7 +498,7 @@ __ham_splitmeta_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __ham_splitmeta_read(dbtp->data, &argp)) != 0)
+	if ((ret = __ham_splitmeta_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]ham_splitmeta: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -659,7 +659,7 @@ __ham_splitdata_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __ham_splitdata_read(dbtp->data, &argp)) != 0)
+	if ((ret = __ham_splitdata_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]ham_splitdata: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -851,7 +851,7 @@ __ham_replace_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __ham_replace_read(dbtp->data, &argp)) != 0)
+	if ((ret = __ham_replace_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]ham_replace: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -1053,7 +1053,7 @@ __ham_newpgno_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __ham_newpgno_read(dbtp->data, &argp)) != 0)
+	if ((ret = __ham_newpgno_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]ham_newpgno: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -1218,7 +1218,7 @@ __ham_ovfl_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __ham_ovfl_read(dbtp->data, &argp)) != 0)
+	if ((ret = __ham_ovfl_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]ham_ovfl: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
diff --git a/db2/hash/hash_conv.c b/db2/hash/hash_conv.c
index 22901af950..9cebe72390 100644
--- a/db2/hash/hash_conv.c
+++ b/db2/hash/hash_conv.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_conv.c	10.3 (Sleepycat) 6/21/97";
+static const char sccsid[] = "@(#)hash_conv.c	10.4 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -20,12 +20,11 @@ static const char sccsid[] = "@(#)hash_conv.c	10.3 (Sleepycat) 6/21/97";
 #include "hash.h"
 
 /*
- * __h_pgin, __ham_pgout --
- *	Convert host-specific page layout to/from the host-independent
- *	format stored on disk.
+ * __ham_pgin --
+ *	Convert host-specific page layout from the host-independent format
+ *	stored on disk.
  *
  * PUBLIC: int __ham_pgin __P((db_pgno_t, void *, DBT *));
- * PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *));
  */
 int
 __ham_pgin(pg, pp, cookie)
@@ -49,9 +48,17 @@ __ham_pgin(pg, pp, cookie)
 
 	if (!pginfo->needswap)
 		return (0);
-	return (pg == PGNO_METADATA ? __ham_mswap(pp) : __db_pgin(pg, pp));
+	return (pg == PGNO_METADATA ?
+	    __ham_mswap(pp) : __db_pgin(pg, pginfo->db_pagesize, pp));
 }
 
+/*
+ * __ham_pgout --
+ *	Convert host-specific page layout to the host-independent format
+ *	stored on disk.
+ *
+ * PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *));
+ */
 int
 __ham_pgout(pg, pp, cookie)
 	db_pgno_t pg;
@@ -63,7 +70,8 @@ __ham_pgout(pg, pp, cookie)
 	pginfo = (DB_PGINFO *)cookie->data;
 	if (!pginfo->needswap)
 		return (0);
-	return (pg == PGNO_METADATA ? __ham_mswap(pp) : __db_pgout(pg, pp));
+	return (pg == PGNO_METADATA ?
+	    __ham_mswap(pp) : __db_pgout(pg, pginfo->db_pagesize, pp));
 }
 
 /*
diff --git a/db2/hash/hash_dup.c b/db2/hash/hash_dup.c
index c9590fa49d..71bd1c5eb0 100644
--- a/db2/hash/hash_dup.c
+++ b/db2/hash/hash_dup.c
@@ -42,7 +42,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_dup.c	10.6 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)hash_dup.c	10.7 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 /*
@@ -99,9 +99,9 @@ __ham_add_dup(hashp, hcp, nval, flags)
 	int flags;
 {
 	DBT pval, tmp_val;
-	HKEYDATA *hk;
 	u_int32_t del_len, new_size;
 	int ret;
+	u_int8_t *hk;
 
 	if (flags == DB_CURRENT && hcp->dpgno == PGNO_INVALID)
 		del_len = hcp->dup_len;
@@ -128,8 +128,8 @@ __ham_add_dup(hashp, hcp, nval, flags)
 	 * the addition of the new item will make the set large, or
 	 * if there isn't enough room on this page to add the next item.
 	 */
-	if (hk->type != H_OFFDUP &&
-	    (hk->type == H_OFFPAGE || ISBIG(hashp, new_size) ||
+	if (HPAGE_PTYPE(hk) != H_OFFDUP &&
+	    (HPAGE_PTYPE(hk) == H_OFFPAGE || ISBIG(hashp, new_size) ||
 	    DUP_SIZE(nval->size) - del_len > P_FREESPACE(hcp->pagep))) {
 
 		if ((ret = __ham_dup_convert(hashp, hcp)) != 0)
@@ -139,16 +139,17 @@ __ham_add_dup(hashp, hcp, nval, flags)
 	}
 
 	/* There are two separate cases here: on page and off page. */
-	if (hk->type != H_OFFDUP) {
-		if (hk->type != H_DUPLICATE) {
-			hk->type = H_DUPLICATE;
+	if (HPAGE_PTYPE(hk) != H_OFFDUP) {
+		if (HPAGE_PTYPE(hk) != H_DUPLICATE) {
+			HPAGE_PTYPE(hk) = H_DUPLICATE;
 			pval.flags = 0;
-			pval.data = hk->data;
+			pval.data = HKEYDATA_DATA(hk);
 			pval.size = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize,
 			    hcp->bndx);
-			if ((ret = __ham_make_dup(&pval, &tmp_val, &hcp->big_data,
-			    &hcp->big_datalen)) != 0 ||
-			    (ret = __ham_replpair(hashp, hcp, &tmp_val, 1)) != 0)
+			if ((ret =
+			    __ham_make_dup(&pval, &tmp_val, &hcp->big_data,
+			    &hcp->big_datalen)) != 0 || (ret =
+			    __ham_replpair(hashp, hcp, &tmp_val, 1)) != 0)
 				return (ret);
 		}
 
@@ -187,8 +188,7 @@ __ham_add_dup(hashp, hcp, nval, flags)
 
 	/* If we get here, then we're on duplicate pages. */
 	if (hcp->dpgno == PGNO_INVALID) {
-		memcpy(&hcp->dpgno,
-		    (u_int8_t *)hk + SSZ(HOFFDUP, pgno), sizeof(db_pgno_t));
+		memcpy(&hcp->dpgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
 		hcp->dndx = 0;
 	}
 
@@ -259,14 +259,13 @@ __ham_dup_convert(hashp, hcp)
 	 * Now put the duplicates onto the new page.
 	 */
 	dbt.flags = 0;
-	switch (((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->type) {
+	switch (HPAGE_PTYPE(H_PAIRDATA(hcp->pagep, hcp->bndx))) {
 	case H_KEYDATA:
 		/* Simple case, one key on page; move it to dup page. */
 		dndx = 0;
 		dbt.size =
 		    LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx);
-		dbt.data =
-		    ((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data;
+		dbt.data = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
 		ret = __db_pitem(hashp->dbp, hcp->dpagep,
 		    (u_int32_t)dndx, BKEYDATA_SIZE(dbt.size), NULL, &dbt);
 		if (ret == 0)
@@ -289,7 +288,7 @@ __ham_dup_convert(hashp, hcp)
 			__ham_dirty_page(hashp, hcp->dpagep);
 		break;
 	case H_DUPLICATE:
-		p = ((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data;
+		p = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
 		pend = p +
 		    LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx);
 
@@ -366,24 +365,23 @@ __ham_check_move(hashp, hcp, add_len)
 {
 	DBT k, d;
 	DB_LSN new_lsn;
-	HKEYDATA *hk;
 	PAGE *next_pagep;
 	db_pgno_t next_pgno;
 	int rectype, ret;
 	u_int32_t new_datalen, old_len;
+	u_int8_t *hk;
 
 	/*
 	 * Check if we can do whatever we need to on this page.  If not,
 	 * then we'll have to move the current element to a new page.
 	 */
-
 	hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
 
 	/*
 	 * If the item is already off page duplicates or an offpage item,
 	 * then we know we can do whatever we need to do in-place
 	 */
-	if (hk->type == H_OFFDUP || hk->type == H_OFFPAGE)
+	if (HPAGE_PTYPE(hk) == H_OFFDUP || HPAGE_PTYPE(hk) == H_OFFPAGE)
 		return (0);
 
 	old_len =
@@ -443,22 +441,25 @@ __ham_check_move(hashp, hcp, add_len)
 		rectype = PUTPAIR;
 		k.flags = 0;
 		d.flags = 0;
-		if (H_PAIRKEY(hcp->pagep, hcp->bndx)->type == H_OFFPAGE) {
+		if (HPAGE_PTYPE(
+		    H_PAIRKEY(hcp->pagep, hcp->bndx)) == H_OFFPAGE) {
 			rectype |= PAIR_KEYMASK;
 			k.data = H_PAIRKEY(hcp->pagep, hcp->bndx);
 			k.size = HOFFPAGE_SIZE;
 		} else {
-			k.data = H_PAIRKEY(hcp->pagep, hcp->bndx)->data;
+			k.data =
+			    HKEYDATA_DATA(H_PAIRKEY(hcp->pagep, hcp->bndx));
 			k.size = LEN_HKEY(hcp->pagep,
 			    hashp->hdr->pagesize, hcp->bndx);
 		}
 
-		if (hk->type == H_OFFPAGE) {
+		if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
 			rectype |= PAIR_DATAMASK;
 			d.data = H_PAIRDATA(hcp->pagep, hcp->bndx);
 			d.size = HOFFPAGE_SIZE;
 		} else {
-			d.data = H_PAIRDATA(hcp->pagep, hcp->bndx)->data;
+			d.data =
+			    HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
 			d.size = LEN_HDATA(hcp->pagep,
 			    hashp->hdr->pagesize, hcp->bndx);
 		}
diff --git a/db2/hash/hash_func.c b/db2/hash/hash_func.c
index 2ef47afb57..1bf12c4948 100644
--- a/db2/hash/hash_func.c
+++ b/db2/hash/hash_func.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_func.c	10.6 (Sleepycat) 7/26/97";
+static const char sccsid[] = "@(#)hash_func.c	10.7 (Sleepycat) 9/16/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -64,7 +64,7 @@ static const char sccsid[] = "@(#)hash_func.c	10.6 (Sleepycat) 7/26/97";
  *
  * PUBLIC: u_int32_t __ham_func2 __P((const void *, u_int32_t));
  */
-#define	dcharhash(h, c)	((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
+#define	DCHARHASH(h, c)	((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
 
 u_int32_t
 __ham_func2(key, len)
@@ -81,7 +81,7 @@ __ham_func2(key, len)
 		c = *k++;
 		if (!c && k > e)
 			break;
-		dcharhash(h, c);
+		DCHARHASH(h, c);
 	}
 	return (h);
 }
diff --git a/db2/hash/hash_page.c b/db2/hash/hash_page.c
index 68c31b14f9..8ba42da1a4 100644
--- a/db2/hash/hash_page.c
+++ b/db2/hash/hash_page.c
@@ -47,10 +47,9 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_page.c	10.18 (Sleepycat) 8/21/97";
+static const char sccsid[] = "@(#)hash_page.c	10.24 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
-
 /*
  * PACKAGE:  hashing
  *
@@ -85,7 +84,7 @@ static const char sccsid[] = "@(#)hash_page.c	10.18 (Sleepycat) 8/21/97";
 static int __ham_lock_bucket __P((DB *, HASH_CURSOR *, db_lockmode_t));
 
 #ifdef DEBUG_SLOW
-static void	 account_page(HTAB *, db_pgno_t, int);
+static void  __account_page(HTAB *, db_pgno_t, int);
 #endif
 
 /*
@@ -121,7 +120,7 @@ __ham_item(hashp, cursorp, mode)
 		 * pointer to be the beginning of the datum.
 		 */
 		memcpy(&cursorp->dup_len,
-		    H_PAIRDATA(cursorp->pagep, cursorp->bndx)->data +
+		    HKEYDATA_DATA(H_PAIRDATA(cursorp->pagep, cursorp->bndx)) +
 		    cursorp->dup_off, sizeof(db_indx_t));
 	else if (F_ISSET(cursorp, H_ISDUP)) {
 		/* Make sure we're not about to run off the page. */
@@ -326,8 +325,8 @@ __ham_item_prev(hashp, cursorp, mode)
 				else {
 					HASH_CURSOR *h;
 					h = cursorp;
-					memcpy(&h->dup_len,
-					    H_PAIRDATA(h->pagep, h->bndx)->data
+					memcpy(&h->dup_len, HKEYDATA_DATA(
+					    H_PAIRDATA(h->pagep, h->bndx))
 					    + h->dup_off - sizeof(db_indx_t),
 					    sizeof(db_indx_t));
 					cursorp->dup_off -=
@@ -481,7 +480,7 @@ __ham_putitem(p, dbt, type)
 	} else {
 		off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size);
 		HOFFSET(p) = p->inp[n] = off;
-		PUT_HKEYDATA(GET_HKEYDATA(p, n), dbt->data, dbt->size, type);
+		PUT_HKEYDATA(P_ENTRY(p, n), dbt->data, dbt->size, type);
 	}
 
 	/* Adjust page info. */
@@ -524,24 +523,24 @@ __ham_del_pair(hashp, cursorp)
 	 * entry referring to the big item.
 	 */
 	ret = 0;
-	if (H_PAIRKEY(p, ndx)->type == H_OFFPAGE) {
-		memcpy(&pgno, (u_int8_t *)GET_HOFFPAGE(p, H_KEYINDEX(ndx)) +
-		    SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t));
+	if (HPAGE_PTYPE(H_PAIRKEY(p, ndx)) == H_OFFPAGE) {
+		memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(p, H_KEYINDEX(ndx))),
+		    sizeof(db_pgno_t));
 		ret = __db_doff(hashp->dbp, pgno, __ham_del_page);
 	}
 
 	if (ret == 0)
-		switch (H_PAIRDATA(p, ndx)->type) {
+		switch (HPAGE_PTYPE(H_PAIRDATA(p, ndx))) {
 		case H_OFFPAGE:
 			memcpy(&pgno,
-			    (u_int8_t *)GET_HOFFPAGE(p, H_DATAINDEX(ndx)) +
-			    SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t));
+			    HOFFPAGE_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
+			    sizeof(db_pgno_t));
 			ret = __db_doff(hashp->dbp, pgno, __ham_del_page);
 			break;
 		case H_OFFDUP:
 			memcpy(&pgno,
-			    (u_int8_t *)GET_HOFFDUP(p, H_DATAINDEX(ndx)) +
-			    SSZ(HOFFDUP, pgno), sizeof(db_pgno_t));
+			    HOFFDUP_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
+			    sizeof(db_pgno_t));
 			ret = __db_ddup(hashp->dbp, pgno, __ham_del_page);
 			break;
 		}
@@ -706,13 +705,12 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
 	DBT *dbt;
 	u_int32_t make_dup;
 {
-	DBT old_dbt, tmp;
+	DBT old_dbt, tdata, tmp;
 	DB_LSN	new_lsn;
-	HKEYDATA *hk;
 	u_int32_t len;
 	int32_t change;
 	int is_big, ret, type;
-	u_int8_t *beg, *dest, *end, *src;
+	u_int8_t *beg, *dest, *end, *hk, *src;
 
 	/*
 	 * Big item replacements are handled in generic code.
@@ -738,11 +736,10 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
 	change = dbt->size - dbt->dlen;
 
 	hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
-	is_big = hk->type == H_OFFPAGE;
+	is_big = HPAGE_PTYPE(hk) == H_OFFPAGE;
 
 	if (is_big)
-		memcpy(&len, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen),
-		    sizeof(u_int32_t));
+		memcpy(&len, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
 	else
 		len = LEN_HKEYDATA(hcp->pagep,
 		    hashp->dbp->pgsize, H_DATAINDEX(hcp->bndx));
@@ -770,13 +767,14 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
 		    &tmp, &hcp->big_key, &hcp->big_keylen)) != 0)
 			return (ret);
 
-		type = hk->type;
 		if (dbt->doff == 0 && dbt->dlen == len) {
 			ret = __ham_del_pair(hashp, hcp);
 			if (ret == 0)
-			    ret = __ham_add_el(hashp, hcp, &tmp, dbt, type);
+			    ret = __ham_add_el(hashp,
+			        hcp, &tmp, dbt, H_KEYDATA);
 		} else {					/* Case B */
-			DBT tdata;
+			type = HPAGE_PTYPE(hk) != H_OFFPAGE ?
+			    HPAGE_PTYPE(hk) : H_KEYDATA;
 			tdata.flags = 0;
 			F_SET(&tdata, DB_DBT_MALLOC | DB_DBT_INTERNAL);
 
@@ -824,7 +822,7 @@ err:		free(tmp.data);
 	 * Set up pointer into existing data. Do it before the log
 	 * message so we can use it inside of the log setup.
 	 */
-	beg = H_PAIRDATA(hcp->pagep, hcp->bndx)->data;
+	beg = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
 	beg += dbt->doff;
 
 	/*
@@ -885,11 +883,11 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt)
 		if (off < 0)
 			len = pagep->inp[ndx] - HOFFSET(pagep);
 		else if ((u_int32_t)off >= LEN_HKEYDATA(pagep, pgsize, ndx)) {
-			len = GET_HKEYDATA(pagep, ndx)->data +
+			len = HKEYDATA_DATA(P_ENTRY(pagep, ndx)) +
 			    LEN_HKEYDATA(pagep, pgsize, ndx) - src;
 			zero_me = 1;
 		} else
-			len = (GET_HKEYDATA(pagep, ndx)->data + off) - src;
+			len = (HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off) - src;
 		dest = src - change;
 		memmove(dest, src, len);
 		if (zero_me)
@@ -901,7 +899,7 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt)
 		HOFFSET(pagep) -= change;
 	}
 	if (off >= 0)
-		memcpy(GET_HKEYDATA(pagep, ndx)->data + off,
+		memcpy(HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off,
 		    dbt->data, dbt->size);
 	else
 		memcpy(P_ENTRY(pagep, ndx), dbt->data, dbt->size);
@@ -1319,7 +1317,7 @@ __ham_new_page(hashp, addr, type, pp)
 		return (ret);
 
 #ifdef DEBUG_SLOW
-	account_page(hashp, addr, 1);
+	__account_page(hashp, addr, 1);
 #endif
 	/* This should not be necessary because page-in should do it. */
 	P_INIT(pagep,
@@ -1398,7 +1396,7 @@ __ham_put_page(dbp, pagep, is_dirty)
 	int32_t is_dirty;
 {
 #ifdef DEBUG_SLOW
-	account_page((HTAB *)dbp->cookie,
+	__account_page((HTAB *)dbp->cookie,
 	    ((BKT *)((char *)pagep - sizeof(BKT)))->pgno, -1);
 #endif
 	return (memp_fput(dbp->mpf, pagep, (is_dirty ? DB_MPOOL_DIRTY : 0)));
@@ -1432,7 +1430,7 @@ __ham_get_page(dbp, addr, pagep)
 	ret = memp_fget(dbp->mpf, &addr, DB_MPOOL_CREATE, pagep);
 #ifdef DEBUG_SLOW
 	if (*pagep != NULL)
-		account_page((HTAB *)dbp->internal, addr, 1);
+		__account_page((HTAB *)dbp->internal, addr, 1);
 #endif
 	return (ret);
 }
@@ -1523,11 +1521,11 @@ __ham_overflow_page(dbp, type, pp)
 #ifdef DEBUG
 /*
  * PUBLIC: #ifdef DEBUG
- * PUBLIC: int bucket_to_page __P((HTAB *, int));
+ * PUBLIC: int __bucket_to_page __P((HTAB *, int));
  * PUBLIC: #endif
  */
 int
-bucket_to_page(hashp, n)
+__bucket_to_page(hashp, n)
 	HTAB *hashp;
 	int n;
 {
@@ -1735,7 +1733,7 @@ __ham_dpair(dbp, p, pndx)
 
 #ifdef DEBUG_SLOW
 static void
-account_page(hashp, pgno, inout)
+__account_page(hashp, pgno, inout)
 	HTAB *hashp;
 	db_pgno_t pgno;
 	int inout;
@@ -1767,7 +1765,8 @@ account_page(hashp, pgno, inout)
 		last--;
 	}
 	for (i = 0; i < last; i++, list[i].times++)
-		if (list[i].times > 20 && !is_bitmap_pgno(hashp, list[i].pgno))
+		if (list[i].times > 20 &&
+		    !__is_bitmap_pgno(hashp, list[i].pgno))
 			(void)fprintf(stderr,
 			    "Warning: pg %lu has been out for %d times\n",
 			    (u_long)list[i].pgno, list[i].times);
diff --git a/db2/hash/hash_rec.c b/db2/hash/hash_rec.c
index 81d9bb5ea8..1b30be337d 100644
--- a/db2/hash/hash_rec.c
+++ b/db2/hash/hash_rec.c
@@ -47,7 +47,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)hash_rec.c	10.12 (Sleepycat) 8/22/97";
+static const char sccsid[] = "@(#)hash_rec.c	10.13 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -364,11 +364,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info)
 	DB *mdbp, *file_dbp;
 	DB_MPOOLFILE *mpf;
 	DBT dbt;
-	HKEYDATA *hk;
 	HTAB *hashp;
 	PAGE *pagep;
 	int32_t grow;
 	int change, cmp_n, cmp_p, getmeta, ret;
+	u_int8_t *hk;
 
 	getmeta = 0;
 	hashp = NULL;				/* XXX: shut the compiler up. */
@@ -421,11 +421,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info)
 		__ham_onpage_replace(pagep,
 		    file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt);
 		if (argp->makedup) {
-			hk = GET_HKEYDATA(pagep, argp->ndx);
+			hk = P_ENTRY(pagep, argp->ndx);
 			if (redo)
-				hk->type = H_DUPLICATE;
+				HPAGE_PTYPE(hk) = H_DUPLICATE;
 			else
-				hk->type = H_KEYDATA;
+				HPAGE_PTYPE(hk) = H_KEYDATA;
 		}
 	}
 
@@ -738,7 +738,7 @@ __ham_ovfl_recover(logp, dbtp, lsnp, redo, info)
 	DBT *dbtp;
 	DB_LSN *lsnp;
 	int redo;
-	 void *info;
+	void *info;
 {
 	__ham_ovfl_args *argp;
 	DB *mdbp, *file_dbp;
diff --git a/db2/include/btree.h b/db2/include/btree.h
index 5cf4224ae6..878096b7b2 100644
--- a/db2/include/btree.h
+++ b/db2/include/btree.h
@@ -43,7 +43,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)btree.h	10.16 (Sleepycat) 8/24/97
+ *	@(#)btree.h	10.17 (Sleepycat) 9/23/97
  */
 
 /* Forward structure declarations. */
@@ -181,6 +181,12 @@ struct __cursor {
 #define	C_DELETED	0x0001
 #define	C_REPLACE	0x0002
 #define	C_REPLACE_SETUP	0x0004
+
+	/*
+	 * Internal cursor held for DB->get; don't hold locks unless involved
+	 * in a TXN.
+	 */
+#define	C_INTERNAL	0x0008
 	u_int32_t	 flags;
 };
 
diff --git a/db2/include/btree_ext.h b/db2/include/btree_ext.h
index dab0f5be4e..9133c58c6b 100644
--- a/db2/include/btree_ext.h
+++ b/db2/include/btree_ext.h
@@ -8,6 +8,7 @@ int __bam_pgin __P((db_pgno_t, void *, DBT *));
 int __bam_pgout __P((db_pgno_t, void *, DBT *));
 int __bam_mswap __P((PAGE *));
 int __bam_cursor __P((DB *, DB_TXN *, DBC **));
+int __bam_c_iclose __P((DB *, DBC *));
 int __bam_get __P((DB *, DB_TXN *, DBT *, DBT *, int));
 int __bam_ovfl_chk __P((DB *, CURSOR *, u_int32_t, int));
 int __bam_ca_delete __P((DB *, db_pgno_t, u_int32_t, CURSOR *));
@@ -51,6 +52,7 @@ int __bam_cdel_recover
 int __ram_open __P((DB *, DBTYPE, DB_INFO *));
 int __ram_cursor __P((DB *, DB_TXN *, DBC **));
 int __ram_close __P((DB *));
+int __ram_c_iclose __P((DB *, DBC *));
 void __ram_ca __P((DB *, db_recno_t, ca_recno_arg));
 int __ram_getno __P((DB *, const DBT *, db_recno_t *, int));
 int __ram_snapshot __P((DB *));
diff --git a/db2/include/db.h.src b/db2/include/db.h.src
index f9b29fa2af..63d9603dba 100644
--- a/db2/include/db.h.src
+++ b/db2/include/db.h.src
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db.h.src	10.67 (Sleepycat) 8/25/97
+ *	@(#)db.h.src	10.77 (Sleepycat) 9/24/97
  */
 
 #ifndef _DB_H_
@@ -67,8 +67,8 @@
 
 #define	DB_VERSION_MAJOR	2
 #define	DB_VERSION_MINOR	3
-#define	DB_VERSION_PATCH	4
-#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.4: (8/20/97)"
+#define	DB_VERSION_PATCH	10
+#define	DB_VERSION_STRING	"Sleepycat Software: DB 2.3.10: (9/24/97)"
 
 typedef	u_int32_t	db_pgno_t;	/* Page number type. */
 typedef	u_int16_t	db_indx_t;	/* Page offset type. */
@@ -329,6 +329,7 @@ struct __db_info {
 #define	DB_NEEDSPLIT		( -9)	/* Page needs to be split. */
 #define	DB_REGISTERED		(-10)	/* Entry was previously registered. */
 #define	DB_SWAPBYTES		(-11)	/* Database needs byte swapping. */
+#define DB_TXN_CKP		(-12)	/* Encountered ckp record in log. */
 
 struct __db_ilock {			/* Internal DB access method lock. */
 	db_pgno_t	pgno;		/* Page being locked. */
@@ -338,7 +339,7 @@ struct __db_ilock {			/* Internal DB access method lock. */
 
 /* DB access method description structure. */
 struct __db {
-	void	*mutex;			/* Synchronization for free threading */
+	void	*mutexp;		/* Synchronization for free threading */
 	DBTYPE	 type;			/* DB access method. */
 	DB_ENV	*dbenv;			/* DB_ENV structure. */
 	DB_ENV	*mp_dbenv;		/* DB_ENV for local mpool creation. */
@@ -640,11 +641,11 @@ extern "C" {
 #endif
 int	memp_close __P((DB_MPOOL *));
 int	memp_fclose __P((DB_MPOOLFILE *));
-int	memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, unsigned long, void *));
+int	memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, int, void *));
 int	memp_fopen __P((DB_MPOOL *, const char *,
 	    int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **));
-int	memp_fput __P((DB_MPOOLFILE *, void *, unsigned long));
-int	memp_fset __P((DB_MPOOLFILE *, void *, unsigned long));
+int	memp_fput __P((DB_MPOOLFILE *, void *, int));
+int	memp_fset __P((DB_MPOOLFILE *, void *, int));
 int	memp_fsync __P((DB_MPOOLFILE *));
 int	memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **));
 int	memp_register __P((DB_MPOOL *, int,
@@ -697,7 +698,7 @@ extern "C" {
 #endif
 int	  txn_abort __P((DB_TXN *));
 int	  txn_begin __P((DB_TXNMGR *, DB_TXN *, DB_TXN **));
-int	  txn_checkpoint __P((const DB_TXNMGR *, long, long));
+int	  txn_checkpoint __P((const DB_TXNMGR *, int, int));
 int	  txn_commit __P((DB_TXN *));
 int	  txn_close __P((DB_TXNMGR *));
 u_int32_t txn_id __P((DB_TXN *));
diff --git a/db2/include/db_185.h.src b/db2/include/db_185.h.src
index 52fb3a0da1..3fbca8bfda 100644
--- a/db2/include/db_185.h.src
+++ b/db2/include/db_185.h.src
@@ -36,7 +36,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	@(#)db_185.h.src	8.3 (Sleepycat) 7/27/97
+ *	@(#)db_185.h.src	8.4 (Sleepycat) 9/16/97
  */
 
 #ifndef _DB_185_H_
@@ -72,6 +72,14 @@
 @u_int32_decl@
 #endif
 
+/*
+ * XXX
+ * SGI/IRIX already has a pgno_t.
+ */
+#ifdef	sgi
+#define	pgno_t	db_pgno_t
+#endif
+
 #define	MAX_PAGE_NUMBER	0xffffffff	/* >= # of pages in a file */
 typedef u_int32_t	pgno_t;
 #define	MAX_PAGE_OFFSET	65535		/* >= # of bytes in a page */
diff --git a/db2/include/db_cxx.h b/db2/include/db_cxx.h
index 506aed845c..611d967ef9 100644
--- a/db2/include/db_cxx.h
+++ b/db2/include/db_cxx.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_cxx.h	10.7 (Sleepycat) 8/22/97
+ *	@(#)db_cxx.h	10.8 (Sleepycat) 9/20/97
  */
 
 #ifndef _DB_CXX_H_
@@ -303,9 +303,9 @@ class _exported DbMpoolFile
 {
 public:
     int close();
-    int get(db_pgno_t *pgnoaddr, unsigned long flags, void *pagep);
-    int put(void *pgaddr, unsigned long flags);
-    int set(void *pgaddr, unsigned long flags);
+    int get(db_pgno_t *pgnoaddr, int flags, void *pagep);
+    int put(void *pgaddr, int flags);
+    int set(void *pgaddr, int flags);
     int sync();
 
     static int open(DbMpool *mp, const char *file,
@@ -391,7 +391,7 @@ class _exported DbTxnMgr
 friend DbEnv;
 public:
     int begin(DbTxn *pid, DbTxn **tid);
-    int checkpoint(long kbyte, long min) const;
+    int checkpoint(int kbyte, int min) const;
     int close();
     int stat(DB_TXN_STAT **statp, void *(*db_malloc)(size_t));
 
diff --git a/db2/include/db_ext.h b/db2/include/db_ext.h
index 1cccb47617..b18b10ff7f 100644
--- a/db2/include/db_ext.h
+++ b/db2/include/db_ext.h
@@ -57,8 +57,8 @@ int __db_noop_print
 int __db_noop_read __P((void *, __db_noop_args **));
 int __db_init_print __P((DB_ENV *));
 int __db_init_recover __P((DB_ENV *));
-int __db_pgin __P((db_pgno_t, void *));
-int __db_pgout __P((db_pgno_t, void *));
+int __db_pgin __P((db_pgno_t, size_t, void *));
+int __db_pgout __P((db_pgno_t, size_t, void *));
 int __db_dispatch __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __db_add_recovery __P((DB_ENV *,
    int (*)(DB_LOG *, DBT *, DB_LSN *, int, void *), u_int32_t));
diff --git a/db2/include/db_int.h.src b/db2/include/db_int.h.src
index b60e5002e5..ebadb35d36 100644
--- a/db2/include/db_int.h.src
+++ b/db2/include/db_int.h.src
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_int.h.src	10.28 (Sleepycat) 8/20/97
+ *	@(#)db_int.h.src	10.30 (Sleepycat) 9/23/97
  */
 
 #ifndef _DB_INTERNAL_H_
@@ -177,11 +177,11 @@ typedef struct _db_mutex_t {
 /* Lock/unlock a DB thread. */
 #define	DB_THREAD_LOCK(dbp)						\
 	(F_ISSET(dbp, DB_AM_THREAD) ?					\
-	    __db_mutex_lock((db_mutex_t *)(dbp)->mutex,  -1,		\
+	    __db_mutex_lock((db_mutex_t *)(dbp)->mutexp,  -1,		\
 	        (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
 #define	DB_THREAD_UNLOCK(dbp)						\
 	(F_ISSET(dbp, DB_AM_THREAD) ?					\
-	    __db_mutex_unlock((db_mutex_t *)(dbp)->mutex,  -1) : 0)
+	    __db_mutex_unlock((db_mutex_t *)(dbp)->mutexp,  -1) : 0)
 
 /* Btree/recno local statistics structure. */
 struct __db_bt_lstat;	typedef struct __db_bt_lstat DB_BTREE_LSTAT;
@@ -306,14 +306,6 @@ typedef struct __dbpginfo {
  * Transactions and recovery.
  *******************************************************/
 /*
- * The locker id space is divided between the transaction manager and the lock
- * manager.  Lockid's start at 0 and go to MAX_LOCKER_ID.  Txn Id's start at
- * MAX_LOCKER_ID + 1 and go up to MAX_TXNID.
- */
-#define	MAX_LOCKER_ID	0x0fffffff
-#define	MAX_TXNID	0xffffffff
-
-/*
  * Out of band value for a lock.  The locks are returned to callers as offsets
  * into the lock regions.  Since the RLAYOUT structure begins all regions, an
  * offset of 0 is guaranteed not to be a valid lock.
diff --git a/db2/include/db_page.h b/db2/include/db_page.h
index cde7ff9f2e..30f6072fc3 100644
--- a/db2/include/db_page.h
+++ b/db2/include/db_page.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_page.h	10.11 (Sleepycat) 9/3/97
+ *	@(#)db_page.h	10.13 (Sleepycat) 9/24/97
  */
 
 #ifndef _DB_PAGE_H_
@@ -273,6 +273,17 @@ typedef struct _db_page {
 #define	H_OFFDUP	4	/* Overflow page of duplicates. */
 
 /*
+ * !!!
+ * Items on hash pages are (potentially) unaligned, so we can never cast the
+ * (page + offset) pointer to an HKEYDATA, HOFFPAGE or HOFFDUP structure, as
+ * we do with B+tree on-page structures.  Because we frequently want the type
+ * field, it requires no alignment, and it's in the same location in all three
+ * structures, there's a pair of macros.
+ */
+#define	HPAGE_PTYPE(p)		(*(u_int8_t *)p)
+#define	HPAGE_TYPE(pg, indx)	(*P_ENTRY(pg, indx))
+
+/*
  * The first and second types are H_KEYDATA and H_DUPLICATE, represented
  * by the HKEYDATA structure:
  *
@@ -294,10 +305,7 @@ typedef struct _hkeydata {
 	u_int8_t  type;		/*    00: Page type. */
 	u_int8_t  data[1];	/* Variable length key/data item. */
 } HKEYDATA;
-
-/* Get a HKEYDATA item for a specific index. */
-#define	GET_HKEYDATA(pg, indx)						\
-	((HKEYDATA *)P_ENTRY(pg, indx))
+#define	HKEYDATA_DATA(p)	(((u_int8_t *)p) + SSZA(HKEYDATA, data))
 
 /*
  * The length of any HKEYDATA item. Note that indx is an element index,
@@ -333,8 +341,8 @@ typedef struct _hkeydata {
 #define H_NUMPAIRS(pg)			(NUM_ENT(pg) / 2)
 #define	H_KEYINDEX(pindx)		(2 * (pindx))
 #define	H_DATAINDEX(pindx)		((2 * (pindx)) + 1)
-#define	H_PAIRKEY(pg, pindx)		GET_HKEYDATA(pg, H_KEYINDEX(pindx))
-#define	H_PAIRDATA(pg, pindx)		GET_HKEYDATA(pg, H_DATAINDEX(pindx))
+#define	H_PAIRKEY(pg, pindx)		P_ENTRY(pg, H_KEYINDEX(pindx))
+#define	H_PAIRDATA(pg, pindx)		P_ENTRY(pg, H_DATAINDEX(pindx))
 #define H_PAIRSIZE(pg, psize, pindx)					\
 	(LEN_HITEM(pg, psize, H_KEYINDEX(pindx)) +			\
 	LEN_HITEM(pg, psize, H_DATAINDEX(pindx)))
@@ -355,9 +363,8 @@ typedef struct _hoffpage {
 	u_int32_t tlen;		/* 08-11: Total length of item. */
 } HOFFPAGE;
 
-/* Get a HOFFPAGE item for a specific index. */
-#define	GET_HOFFPAGE(pg, indx)						\
-	((HOFFPAGE *)P_ENTRY(pg, indx))
+#define	HOFFPAGE_PGNO(p)	(((u_int8_t *)p) + SSZ(HOFFPAGE, pgno))
+#define	HOFFPAGE_TLEN(p)	(((u_int8_t *)p) + SSZ(HOFFPAGE, tlen))
 
 /*
  * Page space required to add a new HOFFPAGE item to the page, with and
@@ -378,10 +385,7 @@ typedef struct _hoffdup {
 	u_int8_t  unused[3];	/* 01-03: Padding, unused. */
 	db_pgno_t pgno;		/* 04-07: Offpage page number. */
 } HOFFDUP;
-
-/* Get a HOFFDUP item for a specific index. */
-#define	GET_HOFFDUP(pg, indx)						\
-	((HOFFDUP *)P_ENTRY(pg, indx))
+#define	HOFFDUP_PGNO(p)		(((u_int8_t *)p) + SSZ(HOFFDUP, pgno))
 
 /*
  * Page space required to add a new HOFFDUP item to the page, with and
diff --git a/db2/include/db_shash.h b/db2/include/db_shash.h
index f695a2bafa..b94e0f1d41 100644
--- a/db2/include/db_shash.h
+++ b/db2/include/db_shash.h
@@ -4,14 +4,14 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)db_shash.h	10.1 (Sleepycat) 4/12/97
+ *	@(#)db_shash.h	10.2 (Sleepycat) 9/16/97
  */
 
 /* Hash Headers */
 typedef	SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
 
 /*
- * __db_hashlookup --
+ * HASHLOOKUP --
  *
  * Look up something in a shared memory hash table.  The "elt" argument
  * should be a key, and cmp_func must know how to compare a key to whatever
@@ -30,7 +30,7 @@ typedef	SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * If the element is not in the hash table, this macro exits with result
  * set to NULL.
  */
-#define	__db_hashlookup(begin, type, field, elt, r, n, hash, cmp) do {	\
+#define	HASHLOOKUP(begin, type, field, elt, r, n, hash, cmp) do {	\
 	DB_HASHTAB *__bucket;						\
 	u_int32_t __ndx;						\
 									\
@@ -43,10 +43,10 @@ typedef	SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
 } while(0)
 
 /*
- * __db_hashinsert --
+ * HASHINSERT --
  *
  * Insert a new entry into the hash table.  This assumes that lookup has
- * failed; don't call it if you haven't already called __db_hashlookup.
+ * failed; don't call it if you haven't already called HASHLOOKUP.
  * begin: the beginning address of the hash table.
  * type: the structure type of the elements that are linked in each bucket.
  * field: the name of the field by which the "type" structures are linked.
@@ -54,7 +54,7 @@ typedef	SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * nelems: the number of buckets in the hash table.
  * hash_func: the hash function that operates on elements of the type of elt
  */
-#define	__db_hashinsert(begin, type, field, elt, n, hash) do {		\
+#define	HASHINSERT(begin, type, field, elt, n, hash) do {		\
 	u_int32_t __ndx;						\
 	DB_HASHTAB *__bucket;						\
 									\
@@ -64,7 +64,7 @@ typedef	SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
 } while(0)
 
 /*
- * __db_hashremove --
+ * HASHREMOVE --
  *	Remove the entry with a key == elt.
  * begin: address of the beginning of the hash table.
  * type: the structure type of the elements that are linked in each bucket.
@@ -75,19 +75,19 @@ typedef	SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * cmp_func: compare elements of the type of elt with those in the table (of
  *	type "type").
  */
-#define	__db_hashremove(begin, type, field, elt, n, hash, cmp) {	\
+#define	HASHREMOVE(begin, type, field, elt, n, hash, cmp) {		\
 	u_int32_t __ndx;						\
 	DB_HASHTAB *__bucket;						\
 	SH_TAILQ_ENTRY *__entp;						\
 									\
 	__ndx = hash(elt) % (n);					\
 	__bucket = &begin[__ndx];					\
-	__db_hashlookup(begin, type, field, elt, __entp, n, hash, cmp);	\
+	HASHLOOKUP(begin, type, field, elt, __entp, n, hash, cmp);	\
 	SH_TAILQ_REMOVE(__bucket, __entp, field, type);			\
 }
 
 /*
- * __db_hashremove_el --
+ * HASHREMOVE_EL --
  *	Given the object "obj" in the table, remove it.
  * begin: address of the beginning of the hash table.
  * type: the structure type of the elements that are linked in each bucket.
@@ -96,7 +96,7 @@ typedef	SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
  * nelems: the number of buckets in the hash table.
  * hash_func: the hash function that operates on elements of the type of elt
  */
-#define	__db_hashremove_el(begin, type, field, obj, n, hash) {		\
+#define	HASHREMOVE_EL(begin, type, field, obj, n, hash) {		\
 	u_int32_t __ndx;						\
 	DB_HASHTAB *__bucket;						\
 									\
diff --git a/db2/include/hash_ext.h b/db2/include/hash_ext.h
index 5ae63dc6ad..32788c7b8a 100644
--- a/db2/include/hash_ext.h
+++ b/db2/include/hash_ext.h
@@ -1,6 +1,7 @@
 /* Do not edit: automatically built by dist/distrib. */
 int __ham_open __P((DB *, DB_INFO *));
 int  __ham_close __P((DB *));
+int __ham_c_iclose __P((DB *, DBC *));
 int __ham_expand_table __P((HTAB *));
 u_int32_t __ham_call_hash __P((HTAB *, u_int8_t *, int32_t));
 int __ham_init_dbt __P((DBT *, u_int32_t, void **, u_int32_t *));
@@ -96,7 +97,7 @@ int __ham_dirty_page __P((HTAB *, PAGE *));
 int __ham_get_page __P((DB *, db_pgno_t, PAGE **));
 int __ham_overflow_page __P((DB *, u_int32_t, PAGE **));
 #ifdef DEBUG
-int bucket_to_page __P((HTAB *, int));
+int __bucket_to_page __P((HTAB *, int));
 #endif
 void __ham_init_ovflpages __P((HTAB *));
 int __ham_get_cpage __P((HTAB *, HASH_CURSOR *, db_lockmode_t));
diff --git a/db2/include/lock.h b/db2/include/lock.h
index 18d29e8740..8f9e81c0fa 100644
--- a/db2/include/lock.h
+++ b/db2/include/lock.h
@@ -4,13 +4,19 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)lock.h	10.7 (Sleepycat) 7/29/97
+ *	@(#)lock.h	10.8 (Sleepycat) 9/23/97
  */
 
 typedef struct __db_lockobj	DB_LOCKOBJ;
 
 #define DB_DEFAULT_LOCK_FILE	"__db_lock.share"
 #define DB_LOCK_DEFAULT_N	5000
+
+/*
+ * The locker id space is divided between the transaction manager and the lock
+ * manager.  Lockid's start at 0 and go to DB_LOCK_MAXID.  Txn Id's start at
+ * DB_LOCK_MAXID + 1 and go up to TXN_INVALID.
+ */
 #define DB_LOCK_MAXID		0x7fffffff
 
 /*
diff --git a/db2/include/log.h b/db2/include/log.h
index 970dfd153a..a9c82fa04d 100644
--- a/db2/include/log.h
+++ b/db2/include/log.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)log.h	10.8 (Sleepycat) 8/18/97
+ *	@(#)log.h	10.9 (Sleepycat) 9/23/97
  */
 
 #ifndef _LOG_H_
@@ -30,11 +30,11 @@ struct __log_persist;	typedef struct __log_persist LOGP;
 /* Macros to lock/unlock the region and threads. */
 #define	LOCK_LOGTHREAD(dblp)						\
 	if (F_ISSET(dblp, DB_AM_THREAD))				\
-		(void)__db_mutex_lock(&(dblp)->mutex, -1,		\
+		(void)__db_mutex_lock((dblp)->mutexp, -1,		\
 		    (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
 #define	UNLOCK_LOGTHREAD(dblp)						\
 	if (F_ISSET(dblp, DB_AM_THREAD))				\
-		(void)__db_mutex_unlock(&(dblp)->mutex, -1);
+		(void)__db_mutex_unlock((dblp)->mutexp, -1);
 #define	LOCK_LOGREGION(dblp)						\
 	(void)__db_mutex_lock(&((RLAYOUT *)(dblp)->lp)->lock,		\
 	    (dblp)->fd, (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
@@ -56,7 +56,7 @@ typedef	struct __db_entry {
  */
 struct __db_log {
 /* These fields need to be protected for multi-threaded support. */
-	db_mutex_t	mutex;		/* Mutex for thread protection. */
+	db_mutex_t	*mutexp;	/* Mutex for thread protection. */
 
 	DB_ENTRY *dbentry;		/* Recovery file-id mapping. */
 #define	DB_GROW_SIZE	64
@@ -86,6 +86,8 @@ struct __db_log {
 	void     *addr;			/* Address of shalloc() region. */
 	int	  fd;			/* Region file descriptor. */
 
+	char	 *dir;			/* Directory argument. */
+
 	u_int32_t flags;		/* Support the DB_AM_XXX flags. */
 };
 
diff --git a/db2/include/log_ext.h b/db2/include/log_ext.h
index d5c9dd6e72..bc63d9dac8 100644
--- a/db2/include/log_ext.h
+++ b/db2/include/log_ext.h
@@ -1,6 +1,6 @@
 /* Do not edit: automatically built by dist/distrib. */
-int __log_find __P((DB_ENV *, LOG *, int *));
-int __log_valid __P((DB_ENV *, LOG *, int));
+int __log_find __P((DB_LOG *, int *));
+int __log_valid __P((DB_LOG *, LOG *, int));
 int __log_register_log
     __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
     DBT *, DBT *, u_int32_t, DBTYPE));
@@ -18,7 +18,7 @@ int __log_init_recover __P((DB_ENV *));
 int __log_findckp __P((DB_LOG *, DB_LSN *));
 int __log_get __P((DB_LOG *, DB_LSN *, DBT *, int, int));
 int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, int));
-int __log_name __P((DB_ENV *, int, char **));
+int __log_name __P((DB_LOG *, int, char **));
 int __log_register_recover
     __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
 int __log_unregister_recover
diff --git a/db2/include/mp.h b/db2/include/mp.h
index 1fe0c752a9..3b71774484 100644
--- a/db2/include/mp.h
+++ b/db2/include/mp.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)mp.h	10.15 (Sleepycat) 8/29/97
+ *	@(#)mp.h	10.16 (Sleepycat) 9/23/97
  */
 
 struct __bh;		typedef struct __bh BH;
@@ -99,7 +99,7 @@ struct __mpoolfile;	typedef struct __mpoolfile MPOOLFILE;
  */
 struct __db_mpool {
 /* These fields need to be protected for multi-threaded support. */
-	db_mutex_t	mutex;		/* Structure lock. */
+	db_mutex_t	*mutexp;	/* Structure lock. */
 
 					/* List of pgin/pgout routines. */
 	LIST_HEAD(__db_mpregh, __db_mpreg) dbregq;
@@ -145,7 +145,7 @@ struct __db_mpreg {
  */
 struct __db_mpoolfile {
 /* These fields need to be protected for multi-threaded support. */
-	db_mutex_t	mutex;		/* Structure lock. */
+	db_mutex_t	*mutexp;	/* Structure lock. */
 
 	int	   fd;			/* Underlying file descriptor. */
 
diff --git a/db2/include/shqueue.h b/db2/include/shqueue.h
index c3e2f4aecc..c596d33e92 100644
--- a/db2/include/shqueue.h
+++ b/db2/include/shqueue.h
@@ -1,38 +1,11 @@
-/*
- * 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.
+/*-
+ * See the file LICENSE for redistribution information.
  *
- * 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.
+ * Copyright (c) 1996, 1997
+ *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)shqueue.h	8.11 (Sleepycat) 7/27/97
+ *	@(#)shqueue.h	8.12 (Sleepycat) 9/10/97
  */
-
 #ifndef	_SYS_SHQUEUE_H_
 #define	_SYS_SHQUEUE_H_
 
diff --git a/db2/include/txn.h b/db2/include/txn.h
index f4e0999b36..8bb3976c1c 100644
--- a/db2/include/txn.h
+++ b/db2/include/txn.h
@@ -4,7 +4,7 @@
  * Copyright (c) 1996, 1997
  *	Sleepycat Software.  All rights reserved.
  *
- *	@(#)txn.h	10.6 (Sleepycat) 7/29/97
+ *	@(#)txn.h	10.10 (Sleepycat) 9/23/97
  */
 #ifndef	_TXN_H_
 #define	_TXN_H_
@@ -14,8 +14,9 @@
  * the region is always created group RW of the group owning the directory.
  */
 #define	DEFAULT_TXN_FILE	"__db_txn.share"
+/* TXN_MINIMUM = (DB_LOCK_MAXID + 1) but this makes compilers complain. */
+#define TXN_MINIMUM		0x80000000
 #define	TXN_INVALID           	0xffffffff /* Maximum number of txn ids. */
-#define TXN_MINIMUM		0x80000000 /* First transaction id */
 
 /*
  * Transaction type declarations.
@@ -36,6 +37,7 @@ typedef struct __txn_detail {
 #define	TXN_ABORTED	2
 #define	TXN_PREPARED	3
 	u_int32_t status;		/* status of the transaction */
+	SH_TAILQ_ENTRY	links;		/* free/active list */
 } TXN_DETAIL;
 
 /*
@@ -45,7 +47,7 @@ typedef struct __txn_detail {
  */
 struct __db_txnmgr {
 /* These fields need to be protected for multi-threaded support. */
-	db_mutex_t	mutex;		/* Synchronization. */
+	db_mutex_t	*mutexp;	/* Synchronization. */
 					/* list of active transactions */
 	TAILQ_HEAD(_chain, __db_txn)	txn_chain;
 
@@ -57,11 +59,14 @@ struct __db_txnmgr {
 	u_int		 flags;		/* DB_TXN_NOSYNC, DB_THREAD */
 	size_t		 reg_size;	/* how large we think the region is */
 	DB_TXNREGION	*region;	/* address of shared memory region */
+	void		*mem;		/* address of the shalloc space */
 };
 
 /*
  * Layout of the shared memory region.
- *
+ * The region consists of a DB_TXNREGION structure followed by a large
+ * pool of shalloc'd memory which is used to hold TXN_DETAIL structures
+ * and thread mutexes (which are dynamically allocated).
  */
 struct __db_txnregion {
 	RLAYOUT		hdr;		/* Shared memory region header. */
@@ -69,7 +74,6 @@ struct __db_txnregion {
 	u_int32_t	version;	/* version number */
 	u_int32_t	maxtxns;	/* maximum number of active txns */
 	u_int32_t	last_txnid;	/* last transaction id given out */
-	u_int32_t	free_txn;	/* head of transaction free list */
 	DB_LSN		pending_ckp;	/* last checkpoint did not finish */
 	DB_LSN		last_ckp;	/* lsn of the last checkpoint */
 	time_t		time_ckp;	/* time of last checkpoint */
@@ -78,20 +82,25 @@ struct __db_txnregion {
 	u_int32_t	naborts;	/* number of aborted transactions */
 	u_int32_t	ncommits;	/* number of committed transactions */
 	u_int32_t	nbegins;	/* number of begun transactions */
-	TXN_DETAIL	table[1];	/* array of TXN structures */
+	SH_TAILQ_HEAD(_active) active_txn;	/* active transaction list */
 };
 
+/*
+ * Make the region large enough to hold N  transaction detail structures
+ * plus some space to hold thread handles and the beginning of the shalloc
+ * region.
+ */
 #define	TXN_REGION_SIZE(N)						\
-			(sizeof(DB_TXNREGION) + N * sizeof(DB_TXN))
+	(sizeof(DB_TXNREGION) + N * sizeof(TXN_DETAIL) + 1000)
 
 /* Macros to lock/unlock the region and threads. */
 #define	LOCK_TXNTHREAD(tmgrp)						\
 	if (F_ISSET(tmgrp, DB_THREAD))					\
-		(void)__db_mutex_lock(&(tmgrp)->mutex, -1,		\
+		(void)__db_mutex_lock((tmgrp)->mutexp, -1,		\
 		    (tmgrp)->dbenv == NULL ? NULL : (tmgrp)->dbenv->db_yield)
 #define	UNLOCK_TXNTHREAD(tmgrp)						\
 	if (F_ISSET(tmgrp, DB_THREAD))					\
-		(void)__db_mutex_unlock(&(tmgrp)->mutex, -1)
+		(void)__db_mutex_unlock((tmgrp)->mutexp, -1)
 
 #define	LOCK_TXNREGION(tmgrp)						\
 	(void)__db_mutex_lock(&(tmgrp)->region->hdr.lock,(tmgrp)->fd,	\
diff --git a/db2/lock/lock.c b/db2/lock/lock.c
index 8fc91334a7..a2a3b208f2 100644
--- a/db2/lock/lock.c
+++ b/db2/lock/lock.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)lock.c	10.31 (Sleepycat) 8/17/97";
+static const char sccsid[] = "@(#)lock.c	10.36 (Sleepycat) 9/24/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -201,7 +201,7 @@ lock_open(path, flags, mode, dbenv, ltp)
 	 * Create the lock table structure.
 	 */
 	if ((lt = (DB_LOCKTAB *)calloc(1, sizeof(DB_LOCKTAB))) == NULL) {
-		__db_err(dbenv, "%s", strerror(errno));
+		__db_err(dbenv, "%s", strerror(ENOMEM));
 		return (ENOMEM);
 	}
 	lt->dbenv = dbenv;
@@ -319,8 +319,10 @@ lock_vec(lt, locker, flags, list, nlist, elistp)
 		case DB_LOCK_GET:
 			ret = __lock_get_internal(lt, locker, flags,
 			    list[i].obj, list[i].mode, &lp);
-			if (ret == 0)
+			if (ret == 0) {
 				list[i].lock = LOCK_TO_OFFSET(lt, lp);
+				lt->region->nrequests++;
+			}
 			break;
 		case DB_LOCK_PUT:
 			lp = OFFSET_TO_LOCK(lt, list[i].lock);
@@ -351,7 +353,7 @@ lock_vec(lt, locker, flags, list, nlist, elistp)
 		case DB_LOCK_PUT_OBJ:
 
 			/* Look up the object in the hash table. */
-			__db_hashlookup(lt->hashtab, __db_lockobj, links,
+			HASHLOOKUP(lt->hashtab, __db_lockobj, links,
 			    list[i].obj, sh_obj, lt->region->table_size,
 			    __lock_ohash, __lock_cmp);
 			if (sh_obj == NULL) {
@@ -596,8 +598,8 @@ __lock_put_internal(lt, lockp, do_all)
 
 	/* Check if object should be reclaimed. */
 	if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL) {
-		__db_hashremove_el(lt->hashtab, __db_lockobj, links, sh_obj,
-		    lt->region->table_size, __lock_lhash);
+		HASHREMOVE_EL(lt->hashtab, __db_lockobj,
+		    links, sh_obj, lt->region->table_size, __lock_lhash);
 		__db_shalloc_free(lt->mem, SH_DBT_PTR(&sh_obj->lockobj));
 		SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, sh_obj, links,
 		    __db_lockobj);
@@ -676,8 +678,12 @@ __lock_get_internal(lt, locker, flags, obj, lock_mode, lockp)
 	 * Now we have a lock and an object and we need to see if we should
 	 * grant the lock.  We use a FIFO ordering so we can only grant a
 	 * new lock if it does not conflict with anyone on the holders list
-	 * OR anyone on the waiters list.  In case of conflict, we put the
-	 * new lock on the end of the waiters list.
+	 * OR anyone on the waiters list.  The reason that we don't grant if
+	 * there's a conflict is that this can lead to starvation (a writer
+	 * waiting on a popularly read item will never ben granted).  The
+	 * downside of this is that a waiting reader can prevent an upgrade
+	 * from reader to writer, which is not uncommon.  In case of conflict,
+	 * we put the new lock on the end of the waiters list.
 	 */
 	for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock);
 	    lp != NULL;
@@ -1042,7 +1048,7 @@ __lock_dump_locker(lt, op)
 
 	ptr = SH_DBT_PTR(&op->lockobj);
 	memcpy(&locker, ptr, sizeof(u_int32_t));
-	printf("L %lu", (u_long)locker);
+	printf("L %lx", (u_long)locker);
 
 	lp = SH_LIST_FIRST(&op->heldby, __db_lock);
 	if (lp == NULL) {
@@ -1095,7 +1101,7 @@ __lock_is_locked(lt, locker, dbt, mode)
 	lrp = lt->region;
 
 	/* Look up the object in the hash table. */
-	__db_hashlookup(lt->hashtab, __db_lockobj, links,
+	HASHLOOKUP(lt->hashtab, __db_lockobj, links,
 	    dbt, sh_obj, lrp->table_size, __lock_ohash, __lock_cmp);
 	if (sh_obj == NULL)
 		return (0);
@@ -1171,7 +1177,7 @@ __lock_printlock(lt, lp, ispgno)
 		stat = "UNKNOWN";
 		break;
 	}
-	printf("\t%lu\t%s\t%lu\t%s\t",
+	printf("\t%lx\t%s\t%lu\t%s\t",
 	    (u_long)lp->holder, mode, (u_long)lp->refcount, stat);
 
 	lockobj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj);
@@ -1243,11 +1249,11 @@ __lock_getobj(lt, locker, dbt, type, objp)
 
 	/* Look up the object in the hash table. */
 	if (type == DB_LOCK_OBJTYPE) {
-		__db_hashlookup(lt->hashtab, __db_lockobj, links, dbt, sh_obj,
+		HASHLOOKUP(lt->hashtab, __db_lockobj, links, dbt, sh_obj,
 		    lrp->table_size, __lock_ohash, __lock_cmp);
 		obj_size = dbt->size;
 	} else {
-		__db_hashlookup(lt->hashtab, __db_lockobj, links, locker,
+		HASHLOOKUP(lt->hashtab, __db_lockobj, links, locker,
 		    sh_obj, lrp->table_size, __lock_locker_hash,
 		    __lock_locker_cmp);
 		obj_size = sizeof(locker);
@@ -1288,8 +1294,8 @@ __lock_getobj(lt, locker, dbt, type, objp)
 		sh_obj->lockobj.size = obj_size;
 		sh_obj->lockobj.off = SH_PTR_TO_OFF(&sh_obj->lockobj, p);
 
-		__db_hashinsert(lt->hashtab, __db_lockobj, links, sh_obj,
-		    lrp->table_size, __lock_lhash);
+		HASHINSERT(lt->hashtab,
+		    __db_lockobj, links, sh_obj, lrp->table_size, __lock_lhash);
 
 		if (type == DB_LOCK_LOCKER)
 			lrp->nlockers++;
@@ -1325,8 +1331,8 @@ __lock_freeobj(lt, obj)
 	DB_LOCKTAB *lt;
 	DB_LOCKOBJ *obj;
 {
-	__db_hashremove_el(lt->hashtab, __db_lockobj, links,
-	    obj, lt->region->table_size, __lock_lhash);
+	HASHREMOVE_EL(lt->hashtab,
+	    __db_lockobj, links, obj, lt->region->table_size, __lock_lhash);
 	__db_shalloc_free(lt->mem, SH_DBT_PTR(&obj->lockobj));
 	SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, obj, links, __db_lockobj);
 }
diff --git a/db2/lock/lock_deadlock.c b/db2/lock/lock_deadlock.c
index f753958b21..f947f901c3 100644
--- a/db2/lock/lock_deadlock.c
+++ b/db2/lock/lock_deadlock.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)lock_deadlock.c	10.20 (Sleepycat) 8/21/97";
+static const char sccsid[] = "@(#)lock_deadlock.c	10.21 (Sleepycat) 9/6/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -300,8 +300,8 @@ retry:	count = lt->region->nlockers;
 			for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock);
 			    lp != NULL;
 			    lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
-				if ((__set_errno(__lock_getobj(lt, lp->holder,
-				    NULL, DB_LOCK_LOCKER, &lockerp))) != 0) {
+				if (__lock_getobj(lt, lp->holder,
+				    NULL, DB_LOCK_LOCKER, &lockerp) != 0) {
 					__db_err(dbenv,
 					    "warning unable to find object");
 					continue;
@@ -472,8 +472,7 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
 	 * Alloc space to print 10 bytes per item waited on.
 	 */
 	if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) {
-		__set_errno(ENOMEM);
-		__db_err(dbenv, "%s", strerror(errno));
+		__db_err(dbenv, "%s", strerror(ENOMEM));
 		return;
 	}
 
diff --git a/db2/log/log.c b/db2/log/log.c
index d3e5183588..893c1ee402 100644
--- a/db2/log/log.c
+++ b/db2/log/log.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log.c	10.25 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)log.c	10.27 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -29,7 +29,7 @@ static const char sccsid[] = "@(#)log.c	10.25 (Sleepycat) 8/27/97";
 #include "txn_auto.h"
 #include "common_ext.h"
 
-static int __log_recover __P((DB_ENV *, DB_LOG *));
+static int __log_recover __P((DB_LOG *));
 
 /*
  * log_open --
@@ -70,14 +70,15 @@ log_open(path, flags, mode, dbenv, lpp)
 	if ((dblp = (DB_LOG *)calloc(1, sizeof(DB_LOG))) == NULL)
 		return (ENOMEM);
 
+	if (path != NULL && (dblp->dir = strdup(path)) == NULL) {
+		free(dblp);
+		return (ENOMEM);
+	}
+
 	dblp->dbenv = dbenv;
 	dblp->lfd = -1;
 	ZERO_LSN(dblp->c_lsn);
 	dblp->c_fd = -1;
-	if (LF_ISSET(DB_THREAD)) {
-		F_SET(dblp, DB_AM_THREAD);
-		(void)__db_mutex_init(&dblp->mutex, -1);
-	}
 
 	/*
 	 * The log region isn't fixed size because we store the registered
@@ -114,7 +115,7 @@ retry:	if (LF_ISSET(DB_CREATE)) {
 
 			newregion = 1;
 		} else if (ret != EEXIST)
-			return (ret);
+			goto err;
 	}
 
 	/* If we didn't or couldn't create the region, try and join it. */
@@ -129,7 +130,7 @@ retry:	if (LF_ISSET(DB_CREATE)) {
 			(void)__db_sleep(1, 0);
 			goto retry;
 		}
-		return (ret);
+		goto err;
 	}
 
 	/* Set up the common information. */
@@ -137,19 +138,49 @@ retry:	if (LF_ISSET(DB_CREATE)) {
 	dblp->addr = (u_int8_t *)dblp->maddr + sizeof(LOG);
 	dblp->fd = fd;
 
+	/* Initialize thread information. */
+	if (LF_ISSET(DB_THREAD)) {
+		F_SET(dblp, DB_AM_THREAD);
+
+		if (!newregion)
+			LOCK_LOGREGION(dblp);
+		if ((ret = __db_shalloc(dblp->addr,
+		    sizeof(db_mutex_t), MUTEX_ALIGNMENT, &dblp->mutexp)) == 0)
+			(void)__db_mutex_init(dblp->mutexp, -1);
+		if (!newregion)
+			UNLOCK_LOGREGION(dblp);
+		if (ret != 0) {
+			(void)log_close(dblp);
+			if (newregion)
+				(void)log_unlink(path, 1, dbenv);
+			return (ret);
+		}
+	}
+
 	/*
 	 * If doing recovery, try and recover any previous log files
 	 * before releasing the lock.
 	 */
 	if (newregion) {
-		if ((ret = __log_recover(dbenv, dblp)) != 0) {
-			log_unlink(path, 1, dbenv);
+		ret = __log_recover(dblp);
+		UNLOCK_LOGREGION(dblp);
+
+		if (ret != 0) {
+			(void)log_close(dblp);
+			(void)log_unlink(path, 1, dbenv);
 			return (ret);
 		}
-		UNLOCK_LOGREGION(dblp);
 	}
 	*lpp = dblp;
 	return (0);
+
+err:	/*
+	 * We never get here with an allocated thread-mutex, so we do
+	 * not have to worry about freeing it.
+	 */
+	FREE(dblp, sizeof(DB_LOG));
+	return (ret);
+
 }
 
 /*
@@ -157,8 +188,7 @@ retry:	if (LF_ISSET(DB_CREATE)) {
  *	Recover a log.
  */
 static int
-__log_recover(dbenv, dblp)
-	DB_ENV *dbenv;
+__log_recover(dblp)
 	DB_LOG *dblp;
 {
 	DBT dbt;
@@ -173,14 +203,14 @@ __log_recover(dbenv, dblp)
 	 * Find a log file.  If none exist, we simply return, leaving
 	 * everything initialized to a new log.
 	 */
-	if ((ret = __log_find(dbenv, lp, &cnt)) != 0)
+	if ((ret = __log_find(dblp, &cnt)) != 0)
 		return (ret);
 	if (cnt == 0)
 		return (0);
 
 	/* We have a log file name, find the last one. */
 	while (cnt < MAXLFNAME)
-		if (__log_valid(dbenv, lp, ++cnt) != 0) {
+		if (__log_valid(dblp, lp, ++cnt) != 0) {
 			--cnt;
 			break;
 		}
@@ -263,7 +293,7 @@ __log_recover(dbenv, dblp)
 		lp->c_lsn.offset = 0;
 	}
 
-	__db_err(dbenv,
+	__db_err(dblp->dbenv,
 	    "Recovering the log: last valid LSN: file: %lu offset %lu",
 	    (u_long)lp->lsn.file, (u_long)lp->lsn.offset);
 
@@ -277,12 +307,11 @@ __log_recover(dbenv, dblp)
  * __log_find --
  *	Try to find a log file.
  *
- * PUBLIC: int __log_find __P((DB_ENV *, LOG *, int *));
+ * PUBLIC: int __log_find __P((DB_LOG *, int *));
  */
 int
-__log_find(dbenv, lp, valp)
-	DB_ENV *dbenv;
-	LOG *lp;
+__log_find(dblp, valp)
+	DB_LOG *dblp;
 	int *valp;
 {
 	int cnt, fcnt, logval, ret;
@@ -290,7 +319,7 @@ __log_find(dbenv, lp, valp)
 	char **names, *p, *q;
 
 	/* Find the directory name. */
-	if ((ret = __log_name(dbenv, 1, &p)) != 0)
+	if ((ret = __log_name(dblp, 1, &p)) != 0)
 		return (ret);
 	if ((q = __db_rpath(p)) == NULL)
 		dir = PATH_DOT;
@@ -300,7 +329,7 @@ __log_find(dbenv, lp, valp)
 	}
 
 	/* Get the list of file names. */
-	ret = __db_dir(dbenv, dir, &names, &fcnt);
+	ret = __db_dir(dblp->dbenv, dir, &names, &fcnt);
 	FREES(p);
 	if (ret != 0)
 		return (ret);
@@ -314,14 +343,14 @@ __log_find(dbenv, lp, valp)
 		if (strncmp(names[cnt], "log.", sizeof("log.") - 1) == 0) {
 			logval = atoi(names[cnt] + 4);
 			if (logval != 0 &&
-			    __log_valid(dbenv, lp, logval) == 0) {
+			    __log_valid(dblp, dblp->lp, logval) == 0) {
 				*valp = logval;
 				break;
 			}
 		}
 
 	/* Discard the list. */
-	__db_dirf(dbenv, names, fcnt);
+	__db_dirf(dblp->dbenv, names, fcnt);
 
 	return (ret);
 }
@@ -330,11 +359,11 @@ __log_find(dbenv, lp, valp)
  * log_valid --
  *	Validate a log file.
  *
- * PUBLIC: int __log_valid __P((DB_ENV *, LOG *, int));
+ * PUBLIC: int __log_valid __P((DB_LOG *, LOG *, int));
  */
 int
-__log_valid(dbenv, lp, cnt)
-	DB_ENV *dbenv;
+__log_valid(dblp, lp, cnt)
+	DB_LOG *dblp;
 	LOG *lp;
 	int cnt;
 {
@@ -343,7 +372,7 @@ __log_valid(dbenv, lp, cnt)
 	int fd, ret;
 	char *p;
 
-	if ((ret = __log_name(dbenv, cnt, &p)) != 0)
+	if ((ret = __log_name(dblp, cnt, &p)) != 0)
 		return (ret);
 
 	fd = -1;
@@ -357,7 +386,7 @@ __log_valid(dbenv, lp, cnt)
 			ret = EIO;
 		if (fd != -1) {
 			(void)__db_close(fd);
-			__db_err(dbenv,
+			__db_err(dblp->dbenv,
 			    "Ignoring log file: %s: %s", p, strerror(ret));
 		}
 		goto err;
@@ -365,14 +394,14 @@ __log_valid(dbenv, lp, cnt)
 	(void)__db_close(fd);
 
 	if (persist.magic != DB_LOGMAGIC) {
-		__db_err(dbenv,
+		__db_err(dblp->dbenv,
 		    "Ignoring log file: %s: magic number %lx, not %lx",
 		    p, (u_long)persist.magic, (u_long)DB_LOGMAGIC);
 		ret = EINVAL;
 		goto err;
 	}
 	if (persist.version < DB_LOGOLDVER || persist.version > DB_LOGVERSION) {
-		__db_err(dbenv,
+		__db_err(dblp->dbenv,
 		    "Ignoring log file: %s: unsupported log version %lu",
 		    p, (u_long)persist.version);
 		ret = EINVAL;
@@ -401,6 +430,13 @@ log_close(dblp)
 
 	ret = 0;
 
+	/* Discard the per-thread pointer. */
+	if (dblp->mutexp != NULL) {
+		LOCK_LOGREGION(dblp);
+		__db_shalloc_free(dblp->addr, dblp->mutexp);
+		UNLOCK_LOGREGION(dblp);
+	}
+
 	/* Close the region. */
 	if ((t_ret =
 	    __db_rclose(dblp->dbenv, dblp->fd, dblp->maddr)) != 0 && ret == 0)
@@ -414,10 +450,12 @@ log_close(dblp)
 	if (dblp->c_fd != -1 &&
 	    (t_ret = __db_close(dblp->c_fd)) != 0 && ret == 0)
 		ret = t_ret;
-
-	/* Free the structure. */
 	if (dblp->dbentry != NULL)
 		FREE(dblp->dbentry, (dblp->dbentry_cnt * sizeof(DB_ENTRY)));
+	if (dblp->dir != NULL)
+		FREES(dblp->dir);
+
+	/* Free the structure. */
 	FREE(dblp, sizeof(DB_LOG));
 
 	return (ret);
diff --git a/db2/log/log_archive.c b/db2/log/log_archive.c
index 0d6c3f2bea..6904a2c726 100644
--- a/db2/log/log_archive.c
+++ b/db2/log/log_archive.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_archive.c	10.23 (Sleepycat) 8/23/97";
+static const char sccsid[] = "@(#)log_archive.c	10.26 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -27,18 +27,18 @@ static const char sccsid[] = "@(#)log_archive.c	10.23 (Sleepycat) 8/23/97";
 #include "clib_ext.h"
 #include "common_ext.h"
 
-static int absname __P((char *, char *, char **));
-static int build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t)));
-static int cmpfunc __P((const void *, const void *));
-static int usermem __P((char ***, void *(*)(size_t)));
+static int __absname __P((char *, char *, char **));
+static int __build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t)));
+static int __cmpfunc __P((const void *, const void *));
+static int __usermem __P((char ***, void *(*)(size_t)));
 
 /*
  * log_archive --
  *	Supporting function for db_archive(1).
  */
 int
-log_archive(logp, listp, flags, db_malloc)
-	DB_LOG *logp;
+log_archive(dblp, listp, flags, db_malloc)
+	DB_LOG *dblp;
 	char ***listp;
 	int flags;
 	void *(*db_malloc) __P((size_t));
@@ -54,10 +54,10 @@ log_archive(logp, listp, flags, db_malloc)
 #define	OKFLAGS	(DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG)
 	if (flags != 0) {
 		if ((ret =
-		    __db_fchk(logp->dbenv, "log_archive", flags, OKFLAGS)) != 0)
+		    __db_fchk(dblp->dbenv, "log_archive", flags, OKFLAGS)) != 0)
 			return (ret);
 		if ((ret =
-		    __db_fcchk(logp->dbenv,
+		    __db_fcchk(dblp->dbenv,
 		        "log_archive", flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0)
 			return (ret);
 	}
@@ -68,7 +68,7 @@ log_archive(logp, listp, flags, db_malloc)
 	 * but that's just not possible.
 	 */
 	if (LF_ISSET(DB_ARCH_ABS)) {
-		__set_errno(0);
+		__set_errno (0);
 		if ((pref = getcwd(buf, sizeof(buf))) == NULL)
 			return (errno == 0 ? ENOMEM : errno);
 	} else
@@ -76,19 +76,19 @@ log_archive(logp, listp, flags, db_malloc)
 
 	switch (LF_ISSET(~DB_ARCH_ABS)) {
 	case DB_ARCH_DATA:
-		return (build_data(logp, pref, listp, db_malloc));
+		return (__build_data(dblp, pref, listp, db_malloc));
 	case DB_ARCH_LOG:
 		memset(&rec, 0, sizeof(rec));
-		if (F_ISSET(logp, DB_AM_THREAD))
+		if (F_ISSET(dblp, DB_AM_THREAD))
 			F_SET(&rec, DB_DBT_MALLOC);
-		if ((ret = log_get(logp, &stable_lsn, &rec, DB_LAST)) != 0)
+		if ((ret = log_get(dblp, &stable_lsn, &rec, DB_LAST)) != 0)
 			return (ret);
-		if (F_ISSET(logp, DB_AM_THREAD))
+		if (F_ISSET(dblp, DB_AM_THREAD))
 			free(rec.data);
 		fnum = stable_lsn.file;
 		break;
 	case 0:
-		if ((ret = __log_findckp(logp, &stable_lsn)) != 0) {
+		if ((ret = __log_findckp(dblp, &stable_lsn)) != 0) {
 			if (ret != DB_NOTFOUND)
 				return (ret);
 			*listp = NULL;
@@ -108,7 +108,7 @@ log_archive(logp, listp, flags, db_malloc)
 
 	/* Build an array of the file names. */
 	for (n = 0; fnum > 0; --fnum) {
-		if ((ret = __log_name(logp->dbenv, fnum, &name)) != 0)
+		if ((ret = __log_name(dblp, fnum, &name)) != 0)
 			goto err;
 		if (__db_exists(name, NULL) != 0)
 			break;
@@ -123,7 +123,7 @@ log_archive(logp, listp, flags, db_malloc)
 		}
 
 		if (LF_ISSET(DB_ARCH_ABS)) {
-			if ((ret = absname(pref, name, &array[n])) != 0)
+			if ((ret = __absname(pref, name, &array[n])) != 0)
 				goto err;
 			FREES(name);
 		} else if ((p = __db_rpath(name)) != NULL) {
@@ -146,10 +146,10 @@ log_archive(logp, listp, flags, db_malloc)
 	}
 
 	/* Sort the list. */
-	qsort(array, (size_t)n, sizeof(char *), cmpfunc);
+	qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
 
 	/* Rework the memory. */
-	if ((ret = usermem(&array, db_malloc)) != 0)
+	if ((ret = __usermem(&array, db_malloc)) != 0)
 		goto err;
 
 	*listp = array;
@@ -164,12 +164,12 @@ err:	if (array != NULL) {
 }
 
 /*
- * build_data --
+ * __build_data --
  *	Build a list of datafiles for return.
  */
 static int
-build_data(logp, pref, listp, db_malloc)
-	DB_LOG *logp;
+__build_data(dblp, pref, listp, db_malloc)
+	DB_LOG *dblp;
 	char *pref, ***listp;
 	void *(*db_malloc) __P((size_t));
 {
@@ -187,19 +187,19 @@ build_data(logp, pref, listp, db_malloc)
 	array[0] = NULL;
 
 	memset(&rec, 0, sizeof(rec));
-	if (F_ISSET(logp, DB_AM_THREAD))
+	if (F_ISSET(dblp, DB_AM_THREAD))
 		F_SET(&rec, DB_DBT_MALLOC);
-	for (n = 0, ret = log_get(logp, &lsn, &rec, DB_FIRST);
-	    ret == 0; ret = log_get(logp, &lsn, &rec, DB_NEXT)) {
+	for (n = 0, ret = log_get(dblp, &lsn, &rec, DB_FIRST);
+	    ret == 0; ret = log_get(dblp, &lsn, &rec, DB_NEXT)) {
 		if (rec.size < sizeof(rectype)) {
 			ret = EINVAL;
-			__db_err(logp->dbenv, "log_archive: bad log record");
+			__db_err(dblp->dbenv, "log_archive: bad log record");
 			goto lg_free;
 		}
 
 		memcpy(&rectype, rec.data, sizeof(rectype));
 		if (rectype != DB_log_register) {
-			if (F_ISSET(logp, DB_AM_THREAD)) {
+			if (F_ISSET(dblp, DB_AM_THREAD)) {
 				free(rec.data);
 				rec.data = NULL;
 			}
@@ -207,7 +207,7 @@ build_data(logp, pref, listp, db_malloc)
 		}
 		if ((ret = __log_register_read(rec.data, &argp)) != 0) {
 			ret = EINVAL;
-			__db_err(logp->dbenv,
+			__db_err(dblp->dbenv,
 			    "log_archive: unable to read log record");
 			goto lg_free;
 		}
@@ -231,7 +231,7 @@ lg_free:		if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
 		array[++n] = NULL;
 		free(argp);
 
-		if (F_ISSET(logp, DB_AM_THREAD)) {
+		if (F_ISSET(dblp, DB_AM_THREAD)) {
 			free(rec.data);
 			rec.data = NULL;
 		}
@@ -245,7 +245,7 @@ lg_free:		if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
 	}
 
 	/* Sort the list. */
-	qsort(array, (size_t)n, sizeof(char *), cmpfunc);
+	qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
 
 	/*
 	 * Build the real pathnames, discarding nonexistent files and
@@ -268,7 +268,7 @@ lg_free:		if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
 		}
 
 		/* Get the real name. */
-		if ((ret = __db_appname(logp->dbenv,
+		if ((ret = __db_appname(dblp->dbenv,
 		    DB_APP_DATA, NULL, array[last], NULL, &real_name)) != 0)
 			goto err2;
 
@@ -284,7 +284,7 @@ lg_free:		if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
 		FREES(array[last]);
 		array[last] = NULL;
 		if (pref != NULL) {
-			ret = absname(pref, real_name, &array[last]);
+			ret = __absname(pref, real_name, &array[last]);
 			FREES(real_name);
 			if (ret != 0)
 				goto err2;
@@ -302,7 +302,7 @@ lg_free:		if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
 	array[last] = NULL;
 
 	/* Rework the memory. */
-	if ((ret = usermem(&array, db_malloc)) != 0)
+	if ((ret = __usermem(&array, db_malloc)) != 0)
 		goto err1;
 
 	*listp = array;
@@ -327,11 +327,11 @@ err1:	if (array != NULL) {
 }
 
 /*
- * absname --
+ * __absname --
  *	Return an absolute path name for the file.
  */
 static int
-absname(pref, name, newnamep)
+__absname(pref, name, newnamep)
 	char *pref, *name, **newnamep;
 {
 	size_t l_pref, l_name;
@@ -355,12 +355,12 @@ absname(pref, name, newnamep)
 }
 
 /*
- * usermem --
+ * __usermem --
  *	Create a single chunk of memory that holds the returned information.
  *	If the user has their own malloc routine, use it.
  */
 static int
-usermem(listp, func)
+__usermem(listp, func)
 	char ***listp;
 	void *(*func) __P((size_t));
 {
@@ -406,7 +406,7 @@ usermem(listp, func)
 }
 
 static int
-cmpfunc(p1, p2)
+__cmpfunc(p1, p2)
 	const void *p1, *p2;
 {
 	return (strcmp(*((char **)p1), *((char **)p2)));
diff --git a/db2/log/log_auto.c b/db2/log/log_auto.c
index 59400087ca..ea88a7bff9 100644
--- a/db2/log/log_auto.c
+++ b/db2/log/log_auto.c
@@ -121,7 +121,7 @@ __log_register_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __log_register_read(dbtp->data, &argp)) != 0)
+	if ((ret = __log_register_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]log_register: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -269,7 +269,7 @@ __log_unregister_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __log_unregister_read(dbtp->data, &argp)) != 0)
+	if ((ret = __log_unregister_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]log_unregister: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
diff --git a/db2/log/log_get.c b/db2/log/log_get.c
index 54a58c75fc..3f6df6c33c 100644
--- a/db2/log/log_get.c
+++ b/db2/log/log_get.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_get.c	10.17 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)log_get.c	10.19 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -145,7 +145,7 @@ __log_get(dblp, alsn, dbt, flags, silent)
 		 * Find any log file.  Note, we may have only entered records
 		 * in the buffer, and not yet written a log file.
 		 */
-		if ((ret = __log_find(dblp->dbenv, lp, &cnt)) != 0) {
+		if ((ret = __log_find(dblp, &cnt)) != 0) {
 			__db_err(dblp->dbenv,
 	"log_get: unable to find the first record: no log files found.");
 			goto err2;
@@ -157,7 +157,7 @@ __log_get(dblp, alsn, dbt, flags, silent)
 
 		/* Now go backwards to find the smallest one. */
 		for (; cnt > 1; --cnt)
-			if (__log_valid(dblp->dbenv, NULL, cnt) != 0) {
+			if (__log_valid(dblp, NULL, cnt) != 0) {
 				++cnt;
 				break;
 			}
@@ -223,7 +223,7 @@ retry:
 	 * Acquire a file descriptor.
 	 */
 	if (dblp->c_fd == -1) {
-		if ((ret = __log_name(dblp->dbenv, nlsn.file, &np)) != 0)
+		if ((ret = __log_name(dblp, nlsn.file, &np)) != 0)
 			goto err1;
 		if ((ret = __db_fdopen(np, DB_RDONLY | DB_SEQUENTIAL,
 		    DB_RDONLY | DB_SEQUENTIAL, 0, &dblp->c_fd)) != 0) {
@@ -319,6 +319,7 @@ retry:
 	    &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
 		goto err1;
 	free(tbuf);
+	tbuf = NULL;
 
 cksum:	if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) {
 		if (!silent)
diff --git a/db2/log/log_put.c b/db2/log/log_put.c
index db31f9b0e1..225595f33e 100644
--- a/db2/log/log_put.c
+++ b/db2/log/log_put.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_put.c	10.12 (Sleepycat) 8/20/97";
+static const char sccsid[] = "@(#)log_put.c	10.14 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -416,7 +416,7 @@ log_file(dblp, lsn, namep, len)
 
 	LOCK_LOGREGION(dblp);
 
-	ret = __log_name(dblp->dbenv, lsn->file, &p);
+	ret = __log_name(dblp, lsn->file, &p);
 
 	UNLOCK_LOGREGION(dblp);
 
@@ -453,14 +453,14 @@ __log_newfd(dblp)
 
 	/* Get the path of the new file and open it. */
 	dblp->lfname = dblp->lp->lsn.file;
-	if ((ret = __log_name(dblp->dbenv, dblp->lfname, &p)) != 0)
+	if ((ret = __log_name(dblp, dblp->lfname, &p)) != 0)
 		return (ret);
 	if ((ret = __db_fdopen(p,
 	    DB_CREATE | DB_SEQUENTIAL,
 	    DB_CREATE | DB_SEQUENTIAL,
 	    dblp->lp->persist.mode, &dblp->lfd)) != 0)
 		__db_err(dblp->dbenv,
-		    "log_put: %s: %s", p, strerror(errno));
+		    "log_put: %s: %s", p, strerror(ret));
 	FREES(p);
 	return (ret);
 }
@@ -469,16 +469,17 @@ __log_newfd(dblp)
  * __log_name --
  *	Return the log name for a particular file.
  *
- * PUBLIC: int __log_name __P((DB_ENV *, int, char **));
+ * PUBLIC: int __log_name __P((DB_LOG *, int, char **));
  */
 int
-__log_name(dbenv, fn, np)
-	DB_ENV *dbenv;
-	int fn;
-	char **np;
+__log_name(dblp, fileno, namep)
+	DB_LOG *dblp;
+	char **namep;
+	int fileno;
 {
 	char name[sizeof(LFNAME) + 10];
 
-	(void)snprintf(name, sizeof(name), LFNAME, fn);
-	return (__db_appname(dbenv, DB_APP_LOG, NULL, name, NULL, np));
+	(void)snprintf(name, sizeof(name), LFNAME, fileno);
+	return (__db_appname(dblp->dbenv,
+	    DB_APP_LOG, dblp->dir, name, NULL, namep));
 }
diff --git a/db2/log/log_register.c b/db2/log/log_register.c
index 582eab9408..859b1e5bcb 100644
--- a/db2/log/log_register.c
+++ b/db2/log/log_register.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)log_register.c	10.10 (Sleepycat) 8/20/97";
+static const char sccsid[] = "@(#)log_register.c	10.11 (Sleepycat) 9/15/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -190,8 +190,13 @@ log_unregister(dblp, fid)
 	SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
 	__db_shalloc_free(dblp->addr, fnp);
 
-	/* Remove from the process local table. */
-	__log_rem_logid(dblp, fid);
+	/*
+	 * Remove from the process local table.  If this operation is taking
+	 * place during recovery, then the logid was never added to the table,
+	 * so do not remove it.
+	 */
+	if (!F_ISSET(dblp, DB_AM_RECOVER))
+		__log_rem_logid(dblp, fid);
 
 ret1:	UNLOCK_LOGREGION(dblp);
 
diff --git a/db2/mp/mp_bh.c b/db2/mp/mp_bh.c
index 3d0d053b5f..fb6bc96ae7 100644
--- a/db2/mp/mp_bh.c
+++ b/db2/mp/mp_bh.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_bh.c	10.15 (Sleepycat) 8/29/97";
+static const char sccsid[] = "@(#)mp_bh.c	10.16 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -55,7 +55,7 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 	 * If we find a descriptor on the file that's not open for writing, we
 	 * try and upgrade it to make it writeable.
 	 */
-	LOCKHANDLE(dbmp, &dbmp->mutex);
+	LOCKHANDLE(dbmp, dbmp->mutexp);
 	for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
 	    dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q))
 		if (dbmfp->mfp == mfp) {
@@ -64,7 +64,7 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 				return (0);
 			break;
 		}
-	UNLOCKHANDLE(dbmp, &dbmp->mutex);
+	UNLOCKHANDLE(dbmp, dbmp->mutexp);
 	if (dbmfp != NULL)
 		goto found;
 
@@ -75,12 +75,12 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
 	 * nothing we can do.
 	 */
 	if (mfp->ftype != 0) {
-		LOCKHANDLE(dbmp, &dbmp->mutex);
+		LOCKHANDLE(dbmp, dbmp->mutexp);
 		for (mpreg = LIST_FIRST(&dbmp->dbregq);
 		    mpreg != NULL; mpreg = LIST_NEXT(mpreg, q))
 			if (mpreg->ftype == mfp->ftype)
 				break;
-		UNLOCKHANDLE(dbmp, &dbmp->mutex);
+		UNLOCKHANDLE(dbmp, dbmp->mutexp);
 		if (mpreg == NULL)
 			return (0);
 	}
@@ -135,19 +135,19 @@ __memp_pgread(dbmfp, bhp, can_create)
 	 * Seek to the page location.
 	 */
 	ret = 0;
-	LOCKHANDLE(dbmp, &dbmfp->mutex);
+	LOCKHANDLE(dbmp, dbmfp->mutexp);
 	if (dbmfp->fd == -1 || (ret =
 	    __db_lseek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0) {
 		if (!can_create) {
 			if (dbmfp->fd == -1)
 				ret = EINVAL;
-			UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+			UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 			__db_err(dbmp->dbenv,
 			    "%s: page %lu doesn't exist, create flag not set",
 			    dbmfp->path, (u_long)bhp->pgno);
 			goto err;
 		}
-		UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+		UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 
 		/* Clear any uninitialized data. */
 		memset(bhp->buf, 0, pagesize);
@@ -159,7 +159,7 @@ __memp_pgread(dbmfp, bhp, can_create)
 	 * any valid data is preserved.
 	 */
 	ret = __db_read(dbmfp->fd, bhp->buf, pagesize, &nr);
-	UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+	UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 	if (ret != 0)
 		goto err;
 
@@ -268,10 +268,10 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 	}
 
 	/* Temporary files may not yet have been created. */
-	LOCKHANDLE(dbmp, &dbmfp->mutex);
+	LOCKHANDLE(dbmp, dbmfp->mutexp);
 	if (dbmfp->fd == -1 && ((ret = __db_appname(dbenv, DB_APP_TMP,
 	    NULL, NULL, &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1)) {
-		UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+		UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 		__db_err(dbenv, "unable to create temporary backing file");
 		goto err;
 	}
@@ -282,7 +282,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
 		fail = "seek";
 	else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0)
 		fail = "write";
-	UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+	UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 	if (ret != 0) {
 		/*
 		 * XXX
@@ -380,7 +380,7 @@ __memp_pg(dbmfp, bhp, is_pgin)
 	dbmp = dbmfp->dbmp;
 	mfp = dbmfp->mfp;
 
-	LOCKHANDLE(dbmp, &dbmp->mutex);
+	LOCKHANDLE(dbmp, dbmp->mutexp);
 
 	ftype = mfp->ftype;
 	for (mpreg = LIST_FIRST(&dbmp->dbregq);
@@ -394,7 +394,7 @@ __memp_pg(dbmfp, bhp, is_pgin)
 			dbt.data = ADDR(dbmp, mfp->pgcookie_off);
 			dbtp = &dbt;
 		}
-		UNLOCKHANDLE(dbmp, &dbmp->mutex);
+		UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
 		if (is_pgin) {
 			if (mpreg->pgin != NULL && (ret =
@@ -408,11 +408,11 @@ __memp_pg(dbmfp, bhp, is_pgin)
 	}
 
 	if (mpreg == NULL)
-		UNLOCKHANDLE(dbmp, &dbmp->mutex);
+		UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
 	return (0);
 
-err:	UNLOCKHANDLE(dbmp, &dbmp->mutex);
+err:	UNLOCKHANDLE(dbmp, dbmp->mutexp);
 	__db_err(dbmp->dbenv, "%s: %s failed for page %lu",
 	    dbmfp->path, is_pgin ? "pgin" : "pgout", (u_long)bhp->pgno);
 	return (ret);
diff --git a/db2/mp/mp_fget.c b/db2/mp/mp_fget.c
index 418802a3b9..a0364e92c3 100644
--- a/db2/mp/mp_fget.c
+++ b/db2/mp/mp_fget.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fget.c	10.22 (Sleepycat) 8/19/97";
+static const char sccsid[] = "@(#)mp_fget.c	10.25 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -35,7 +35,7 @@ int
 memp_fget(dbmfp, pgnoaddr, flags, addrp)
 	DB_MPOOLFILE *dbmfp;
 	db_pgno_t *pgnoaddr;
-	u_long flags;
+	int flags;
 	void *addrp;
 {
 	BH *bhp, *tbhp;
@@ -293,7 +293,7 @@ found:		/* Increment the reference count. */
 			__db_err(dbmp->dbenv,
 			    "%s: too many references to page %lu",
 			    dbmfp->path, bhp->pgno);
-			ret = EAGAIN;
+			ret = EINVAL;
 			goto err;
 		}
 		++bhp->ref;
@@ -337,9 +337,9 @@ found:		/* Increment the reference count. */
 		++mfp->stat.st_cache_hit;
 	}
 
-mapret:	LOCKHANDLE(dbmp, &dbmfp->mutex);
+mapret:	LOCKHANDLE(dbmp, dbmfp->mutexp);
 	++dbmfp->pinref;
-	UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+	UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 
 	if (0) {
 err:		/*
diff --git a/db2/mp/mp_fopen.c b/db2/mp/mp_fopen.c
index 1a770bfdf0..5ab807701c 100644
--- a/db2/mp/mp_fopen.c
+++ b/db2/mp/mp_fopen.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fopen.c	10.25 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)mp_fopen.c	10.27 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -28,8 +28,8 @@ static const char sccsid[] = "@(#)mp_fopen.c	10.25 (Sleepycat) 8/27/97";
 #include "common_ext.h"
 
 static int __memp_mf_close __P((DB_MPOOL *, DB_MPOOLFILE *));
-static int __memp_mf_open __P((DB_MPOOL *, DB_MPOOLFILE *,
-    int, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **));
+static int __memp_mf_open __P((DB_MPOOL *,
+    DB_MPOOLFILE *, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **));
 
 /*
  * memp_fopen --
@@ -97,7 +97,6 @@ __memp_fopen(dbmp, path,
 		    path == NULL ? TEMPORARY : path, strerror(ENOMEM));
 		return (ENOMEM);
 	}
-	LOCKINIT(dbmp, &dbmfp->mutex);
 	dbmfp->dbmp = dbmp;
 	dbmfp->fd = -1;
 	if (LF_ISSET(DB_RDONLY))
@@ -141,14 +140,21 @@ __memp_fopen(dbmp, path,
 		}
 	}
 
-	/* Find/allocate the shared file object. */
+	/*
+	 * Find/allocate the shared file objects.  This includes allocating
+	 * space for the per-process thread lock.
+	 */
 	if (needlock)
 		LOCKREGION(dbmp);
-	ret = __memp_mf_open(dbmp, dbmfp, ftype,
-	    F_ISSET(dbmfp, MP_READONLY), pagesize,
+	ret = __memp_mf_open(dbmp, dbmfp, ftype, pagesize,
 	    lsn_offset, pgcookie, fileid, F_ISSET(dbmfp, MP_PATH_TEMP), &mfp);
+	if (ret == 0 &&
+	    F_ISSET(dbmp, MP_LOCKHANDLE) && (ret =
+	    __memp_ralloc(dbmp, sizeof(db_mutex_t), NULL, &dbmfp->mutexp)) == 0)
+		LOCKINIT(dbmp, dbmfp->mutexp);
 	if (needlock)
 		UNLOCKREGION(dbmp);
+
 	if (ret != 0)
 		goto err;
 
@@ -156,11 +162,11 @@ __memp_fopen(dbmp, path,
 
 	/*
 	 * If a file:
-	 *
 	 *	+ is read-only
+	 *	+ isn't temporary
 	 *	+ doesn't require any pgin/pgout support
-	 *	+ is less than mp_mmapsize bytes in size.
-	 *	+ and the DB_NOMMAP flag wasn't set
+	 *	+ the DB_NOMMAP flag wasn't set
+	 *	+ and is less than mp_mmapsize bytes in size
 	 *
 	 * we can mmap it instead of reading/writing buffers.  Don't do error
 	 * checking based on the mmap call failure.  We want to do normal I/O
@@ -176,11 +182,20 @@ __memp_fopen(dbmp, path,
 	 * flatly impossible.  Hope that mmap fails if the file is too large.
 	 */
 #define	DB_MAXMMAPSIZE	(10 * 1024 * 1024)	/* 10 Mb. */
+	if (mfp->can_mmap) {
+		if (!F_ISSET(dbmfp, MP_READONLY))
+			mfp->can_mmap = 0;
+		if (path == NULL)
+			mfp->can_mmap = 0;
+		if (ftype != 0)
+			mfp->can_mmap = 0;
+		if (LF_ISSET(DB_NOMMAP))
+			mfp->can_mmap = 0;
+		if (size > (dbenv == NULL || dbenv->mp_mmapsize == 0 ?
+		    DB_MAXMMAPSIZE : (off_t)dbenv->mp_mmapsize))
+			mfp->can_mmap = 0;
+	}
 	dbmfp->addr = NULL;
-	mfp->can_mmap = F_ISSET(dbmfp, MP_READONLY) &&
-	    ftype == 0 && !LF_ISSET(DB_NOMMAP) && path != NULL &&
-	    size <= (dbenv == NULL || dbenv->mp_mmapsize == 0 ?
-	    DB_MAXMMAPSIZE : (off_t)dbenv->mp_mmapsize);
 	if (mfp->can_mmap) {
 		dbmfp->len = size;
 		if (__db_mmap(dbmfp->fd, dbmfp->len, 1, 1, &dbmfp->addr) != 0) {
@@ -189,14 +204,18 @@ __memp_fopen(dbmp, path,
 		}
 	}
 
-	LOCKHANDLE(dbmp, &dbmp->mutex);
+	LOCKHANDLE(dbmp, dbmp->mutexp);
 	TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);
-	UNLOCKHANDLE(dbmp, &dbmp->mutex);
+	UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
 	*retp = dbmfp;
 	return (0);
 
-err:	if (F_ISSET(dbmfp, MP_PATH_ALLOC))
+err:	/*
+	 * Note that we do not have to free the thread mutex, because we
+	 * never get to here after we have successfully allocated it.
+	 */
+	if (F_ISSET(dbmfp, MP_PATH_ALLOC))
 		FREES(dbmfp->path);
 	if (dbmfp->fd != -1)
 		(void)__db_close(dbmfp->fd);
@@ -211,10 +230,10 @@ err:	if (F_ISSET(dbmfp, MP_PATH_ALLOC))
  */
 static int
 __memp_mf_open(dbmp, dbmfp,
-    ftype, readonly, pagesize, lsn_offset, pgcookie, fileid, istemp, retp)
+    ftype, pagesize, lsn_offset, pgcookie, fileid, istemp, retp)
 	DB_MPOOL *dbmp;
 	DB_MPOOLFILE *dbmfp;
-	int ftype, readonly, lsn_offset, istemp;
+	int ftype, lsn_offset, istemp;
 	size_t pagesize;
 	DBT *pgcookie;
 	u_int8_t *fileid;
@@ -255,13 +274,8 @@ __memp_mf_open(dbmp, dbmfp,
 				mfp = NULL;
 				goto ret1;
 			}
-			/*
-			 * Found it: increment the reference count and update
-			 * the mmap-able status.
-			 */
+			/* Found it: increment the reference count. */
 			++mfp->ref;
-			if (!readonly)
-				mfp->can_mmap = 0;
 			goto ret1;
 		}
 
@@ -273,6 +287,7 @@ alloc:	if ((ret = __memp_ralloc(dbmp, sizeof(MPOOLFILE), NULL, &mfp)) != 0)
 	memset(mfp, 0, sizeof(MPOOLFILE));
 	mfp->ref = 1;
 	mfp->ftype = ftype;
+	mfp->can_mmap = 1;
 	mfp->lsn_off = lsn_offset;
 	mfp->stat.st_pagesize = pagesize;
 
@@ -343,9 +358,9 @@ memp_fclose(dbmfp)
 		    dbmfp->path, (u_long)dbmfp->pinref);
 
 	/* Remove the DB_MPOOLFILE structure from the list. */
-	LOCKHANDLE(dbmp, &dbmp->mutex);
+	LOCKHANDLE(dbmp, dbmp->mutexp);
 	TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q);
-	UNLOCKHANDLE(dbmp, &dbmp->mutex);
+	UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
 	/* Close the underlying MPOOLFILE. */
 	(void)__memp_mf_close(dbmp, dbmfp);
@@ -362,11 +377,16 @@ memp_fclose(dbmfp)
 			t_ret = ret;
 	}
 
-	/* Potentially allocated path. */
+	/* Free memory. */
 	if (F_ISSET(dbmfp, MP_PATH_ALLOC))
 		FREES(dbmfp->path);
+	if (dbmfp->mutexp != NULL) {
+		LOCKREGION(dbmp);
+		__db_shalloc_free(dbmp->addr, dbmfp->mutexp);
+		UNLOCKREGION(dbmp);
+	}
 
-	/* Free the DB_MPOOLFILE structure. */
+	/* Discard the DB_MPOOLFILE structure. */
 	FREE(dbmfp, sizeof(DB_MPOOLFILE));
 
 	return (ret);
diff --git a/db2/mp/mp_fput.c b/db2/mp/mp_fput.c
index 5fac8ae76b..9ea7cd9d0d 100644
--- a/db2/mp/mp_fput.c
+++ b/db2/mp/mp_fput.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fput.c	10.10 (Sleepycat) 7/20/97";
+static const char sccsid[] = "@(#)mp_fput.c	10.12 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -31,7 +31,7 @@ int
 memp_fput(dbmfp, pgaddr, flags)
 	DB_MPOOLFILE *dbmfp;
 	void *pgaddr;
-	u_long flags;
+	int flags;
 {
 	BH *bhp;
 	DB_MPOOL *dbmp;
@@ -58,14 +58,14 @@ memp_fput(dbmfp, pgaddr, flags)
 	}
 
 	/* Decrement the pinned reference count. */
-	LOCKHANDLE(dbmp, &dbmfp->mutex);
+	LOCKHANDLE(dbmp, dbmfp->mutexp);
 	if (dbmfp->pinref == 0)
 		__db_err(dbmp->dbenv,
 		    "%s: put: more blocks returned than retrieved",
 		    dbmfp->path);
 	else
 		--dbmfp->pinref;
-	UNLOCKHANDLE(dbmp, &dbmfp->mutex);
+	UNLOCKHANDLE(dbmp, dbmfp->mutexp);
 
 	/*
 	 * If we're mapping the file, there's nothing to do.  Because we can
diff --git a/db2/mp/mp_fset.c b/db2/mp/mp_fset.c
index 588085a358..a3a3dcef9c 100644
--- a/db2/mp/mp_fset.c
+++ b/db2/mp/mp_fset.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_fset.c	10.8 (Sleepycat) 8/19/97";
+static const char sccsid[] = "@(#)mp_fset.c	10.9 (Sleepycat) 9/20/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -30,7 +30,7 @@ int
 memp_fset(dbmfp, pgaddr, flags)
 	DB_MPOOLFILE *dbmfp;
 	void *pgaddr;
-	u_long flags;
+	int flags;
 {
 	BH *bhp;
 	DB_MPOOL *dbmp;
diff --git a/db2/mp/mp_open.c b/db2/mp/mp_open.c
index 257ce1b9e9..f622b1ed26 100644
--- a/db2/mp/mp_open.c
+++ b/db2/mp/mp_open.c
@@ -7,7 +7,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mp_open.c	10.12 (Sleepycat) 7/6/97";
+static const char sccsid[] = "@(#)mp_open.c	10.13 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -56,7 +56,6 @@ memp_open(path, flags, mode, dbenv, retp)
 	/* Create and initialize the DB_MPOOL structure. */
 	if ((dbmp = (DB_MPOOL *)calloc(1, sizeof(DB_MPOOL))) == NULL)
 		return (ENOMEM);
-	LOCKINIT(dbmp, &dbmp->mutex);
 	LIST_INIT(&dbmp->dbregq);
 	TAILQ_INIT(&dbmp->dbmfq);
 
@@ -68,6 +67,17 @@ memp_open(path, flags, mode, dbenv, retp)
 		F_SET(dbmp, MP_ISPRIVATE);
 
 	/*
+	 * XXX
+	 * HP-UX won't permit mutexes to live in anything but shared memory.
+	 * So, we have to instantiate the shared mpool region file on that
+	 * architecture, regardless.  If this turns out to be a performance
+	 * problem, we could probably use anonymous memory instead.
+	 */
+#if defined(__hppa)
+	F_CLR(dbmp, MP_ISPRIVATE);
+#endif
+
+	/*
 	 * Map in the region.  We do locking regardless, as portions of it are
 	 * implemented in common code (if we put the region in a file, that is).
 	 */
@@ -79,12 +89,22 @@ memp_open(path, flags, mode, dbenv, retp)
 	/*
 	 * If there's concurrent access, then we have to lock the region.
 	 * If it's threaded, then we have to lock both the handles and the
-	 * region.
+	 * region, and we need to allocate a mutex for that purpose.
 	 */
 	if (!F_ISSET(dbmp, MP_ISPRIVATE))
 		F_SET(dbmp, MP_LOCKREGION);
-	if (LF_ISSET(DB_THREAD))
+	if (LF_ISSET(DB_THREAD)) {
 		F_SET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION);
+		LOCKREGION(dbmp);
+		ret = __memp_ralloc(dbmp,
+		    sizeof(db_mutex_t), NULL, &dbmp->mutexp);
+		UNLOCKREGION(dbmp);
+		if (ret != 0) {
+			(void)memp_close(dbmp);
+			goto err;
+		}
+		LOCKINIT(dbmp, dbmp->mutexp);
+	}
 
 	*retp = dbmp;
 	return (0);
@@ -119,11 +139,18 @@ memp_close(dbmp)
 		if ((t_ret = memp_fclose(dbmfp)) != 0 && ret == 0)
 			ret = t_ret;
 
+	/* Discard thread mutex. */
+	if (F_ISSET(dbmp, MP_LOCKHANDLE)) {
+		LOCKREGION(dbmp);
+		__db_shalloc_free(dbmp->addr, dbmp->mutexp);
+		UNLOCKREGION(dbmp);
+	}
+
 	/* Close the region. */
 	if ((t_ret = __memp_rclose(dbmp)) && ret == 0)
 		ret = t_ret;
 
-	/* Free the structure. */
+	/* Discard the structure. */
 	FREE(dbmp, sizeof(DB_MPOOL));
 
 	return (ret);
@@ -168,9 +195,9 @@ memp_register(dbmp, ftype, pgin, pgout)
 	 * the most recent registry in the case of multiple entries, so
 	 * we don't have to check for multiple registries.
 	 */
-	LOCKHANDLE(dbmp, &dbmp->mutex);
+	LOCKHANDLE(dbmp, dbmp->mutexp);
 	LIST_INSERT_HEAD(&dbmp->dbregq, mpr, q);
-	UNLOCKHANDLE(dbmp, &dbmp->mutex);
+	UNLOCKHANDLE(dbmp, dbmp->mutexp);
 
 	return (0);
 }
diff --git a/db2/mutex/mutex.c b/db2/mutex/mutex.c
index b23f738ad7..5315b2d3fe 100644
--- a/db2/mutex/mutex.c
+++ b/db2/mutex/mutex.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)mutex.c	10.22 (Sleepycat) 8/21/97";
+static const char sccsid[] = "@(#)mutex.c	10.25 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
diff --git a/db2/os/db_os_dir.c b/db2/os/db_os_dir.c
index 6dabd62049..1206e3faa7 100644
--- a/db2/os/db_os_dir.c
+++ b/db2/os/db_os_dir.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)db_os_dir.c	10.8 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_os_dir.c	10.10 (Sleepycat) 9/17/97";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -60,9 +60,11 @@ __db_dir(dbenv, dir, namesp, cntp)
 	struct _finddata_t fdata;
 	long dirhandle;
 	int finished;
+	char filespec[MAX_PATH];
 
-	if ((dirhandle = _findfirst(dir, &fdata)) == -1) {
-		__db_err(dbenv, "%s: %s", dir, strerror(errno));
+	(void)snprintf(filespec, sizeof(filespec), "%s/*", dir);
+	if ((dirhandle = _findfirst(filespec, &fdata)) == -1) {
+		__db_err(dbenv, "%s: %s", filespec, strerror(errno));
 		return (errno);
 	}
 
diff --git a/db2/progs/db_checkpoint/db_checkpoint.c b/db2/progs/db_checkpoint/db_checkpoint.c
index 4f9b79a7ba..b2a692bba9 100644
--- a/db2/progs/db_checkpoint/db_checkpoint.c
+++ b/db2/progs/db_checkpoint/db_checkpoint.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_checkpoint.c	10.11 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_checkpoint.c	10.12 (Sleepycat) 9/4/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -22,6 +22,7 @@ static const char sccsid[] = "@(#)db_checkpoint.c	10.11 (Sleepycat) 8/27/97";
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #endif
@@ -59,7 +60,7 @@ main(argc, argv)
 	DB_ENV *dbenv;
 	time_t now;
 	long kbytes, minutes, seconds;
-	int ch, rval, verbose;
+	int ch, eval, verbose;
 	char *home, *logfile;
 
 	home = logfile = NULL;
@@ -110,7 +111,7 @@ main(argc, argv)
 	 * to wake up when a checkpoint is necessary.  If we have a "kbytes"
 	 * field set, then we'll check every 30 seconds.
 	 */
-	rval = 0;
+	eval = 0;
 	seconds = kbytes != 0 ? 30 : minutes * 60;
 	while (!interrupted) {
 		(void)__db_sleep(seconds, 0);
@@ -119,23 +120,25 @@ main(argc, argv)
 			(void)time(&now);
 			printf("checkpoint: %s", ctime(&now));
 		}
-		rval = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
-		if (rval < 0)
-			break;
+		errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
 
-		while (rval > 0) {
+		while (errno == DB_INCOMPLETE) {
 			if (verbose)
 				__db_err(dbenv,
 				    "checkpoint did not finish, retrying");
 			(void)__db_sleep(2, 0);
-			rval = txn_checkpoint(dbenv->tx_info, 0, 0);
+			errno = txn_checkpoint(dbenv->tx_info, 0, 0);
 		}
-		if (rval < 0)
+
+		if (errno != 0) {
+			eval = 1;
+			__db_err(dbenv, "checkpoint: %s", strerror(errno));
 			break;
+		}
 	}
 
 	if (logfile != NULL && logpid(logfile, 0))
-		rval = 1;
+		eval = 1;
 
 	if (interrupted) {
 		(void)signal(interrupted, SIG_DFL);
@@ -143,7 +146,7 @@ main(argc, argv)
 		/* NOTREACHED */
 	}
 
-	return (db_appexit(dbenv) || rval ? 1 : 0);
+	return (db_appexit(dbenv) || eval ? 1 : 0);
 }
 
 /*
diff --git a/db2/progs/db_deadlock/db_deadlock.c b/db2/progs/db_deadlock/db_deadlock.c
index 09004f58b3..ec2b53dee7 100644
--- a/db2/progs/db_deadlock/db_deadlock.c
+++ b/db2/progs/db_deadlock/db_deadlock.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_deadlock.c	10.14 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_deadlock.c	10.15 (Sleepycat) 9/4/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
diff --git a/db2/progs/db_dump185/db_dump185.c b/db2/progs/db_dump185/db_dump185.c
index 6e2d95bee0..5ec7673f1b 100644
--- a/db2/progs/db_dump185/db_dump185.c
+++ b/db2/progs/db_dump185/db_dump185.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_dump185.c	10.7 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_dump185.c	10.8 (Sleepycat) 9/21/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -192,7 +192,7 @@ main(argc, argv)
 
 	if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_BTREE, NULL)) == NULL) {
 		if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_HASH, NULL)) == NULL)
-			return (1);
+			err(1, "%s", argv[0]);
 		db_185_hash(dbp, pflag);
 	} else
 		db_185_btree(dbp, pflag);
diff --git a/db2/progs/db_load/db_load.c b/db2/progs/db_load/db_load.c
index 6f69216777..a1ebfa8a11 100644
--- a/db2/progs/db_load/db_load.c
+++ b/db2/progs/db_load/db_load.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_load.c	10.12 (Sleepycat) 8/28/97";
+static const char sccsid[] = "@(#)db_load.c	10.13 (Sleepycat) 9/15/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -59,7 +59,7 @@ main(argc, argv)
 	char **clist, **clp, *home;
 
 	/* Allocate enough room for configuration arguments. */
-	if ((clp = clist = calloc(argc + 1, sizeof(char *))) == NULL)
+	if ((clp = clist = (char **)calloc(argc + 1, sizeof(char *))) == NULL)
 		err(1, NULL);
 
 	home = NULL;
diff --git a/db2/progs/db_recover/db_recover.c b/db2/progs/db_recover/db_recover.c
index d17c4b0c76..55b9b49a79 100644
--- a/db2/progs/db_recover/db_recover.c
+++ b/db2/progs/db_recover/db_recover.c
@@ -11,7 +11,7 @@
 static const char copyright[] =
 "@(#) Copyright (c) 1997\n\
 	Sleepycat Software Inc.  All rights reserved.\n";
-static const char sccsid[] = "@(#)db_recover.c	10.14 (Sleepycat) 8/27/97";
+static const char sccsid[] = "@(#)db_recover.c	10.15 (Sleepycat) 9/21/97";
 #endif
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -24,6 +24,7 @@ static const char sccsid[] = "@(#)db_recover.c	10.14 (Sleepycat) 8/27/97";
 #endif
 
 #include "db_int.h"
+#include "shqueue.h"
 #include "txn.h"
 #include "common_ext.h"
 #include "clib_ext.h"
diff --git a/db2/txn/txn.c b/db2/txn/txn.c
index cb700dc037..9a0d626c3e 100644
--- a/db2/txn/txn.c
+++ b/db2/txn/txn.c
@@ -43,16 +43,10 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)txn.c	10.24 (Sleepycat) 9/3/97";
+static const char sccsid[] = "@(#)txn.c	10.30 (Sleepycat) 9/23/97";
 #endif /* not lint */
 
 
-/*
- * This file contains the top level routines of the transaction library.
- * It assumes that a lock manager and log manager that conform to the db_log(3)
- * and db_lock(3) interfaces exist.
- */
-
 #ifndef NO_SYSTEM_INCLUDES
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -87,10 +81,12 @@ static int __txn_undo __P((DB_TXN *));
 static int __txn_validate_region __P((DB_TXNMGR *));
 
 /*
+ * This file contains the top level routines of the transaction library.
+ * It assumes that a lock manager and log manager that conform to the db_log(3)
+ * and db_lock(3) interfaces exist.
+ *
  * Create and initialize a transaction region in shared memory.
- * 0 means, success.
- * +1 means that the db_create failed, so we did not create the region.
- * -1 means that we got some sort of system error.
+ * Return 0 on success, errno on failure.
  */
 static int
 __txn_create(dbenv, path, mode)
@@ -99,9 +95,8 @@ __txn_create(dbenv, path, mode)
 	u_int mode;
 {
 	DB_TXNREGION *txn_region;
-	TXN_DETAIL *txnp;
 	time_t now;
-	int fd, i, maxtxns, ret;
+	int fd, maxtxns, ret;
 
 	maxtxns = dbenv->tx_max != 0 ? dbenv->tx_max : 1000;
 	(void)time(&now);
@@ -120,17 +115,12 @@ __txn_create(dbenv, path, mode)
 	/* XXX If we ever do more types of locking and logging, this changes. */
 	txn_region->logtype = 0;
 	txn_region->locktype = 0;
-	txn_region->free_txn = 0;
 	txn_region->time_ckp = now;
 	ZERO_LSN(txn_region->last_ckp);
 	ZERO_LSN(txn_region->pending_ckp);
-
-	for (txnp = &txn_region->table[0], i = 0; i < maxtxns; i++, txnp++) {
-		ZERO_LSN(txnp->begin_lsn);
-		txnp->status = TXN_UNALLOC;
-		txnp->txnid = i + 1;
-	}
-	txn_region->table[maxtxns - 1].txnid = TXN_INVALID;
+	SH_TAILQ_INIT(&txn_region->active_txn);
+	__db_shalloc_init((void *)&txn_region[1],
+	    TXN_REGION_SIZE(maxtxns) - sizeof(DB_TXNREGION));
 
 	/* Unlock the region. */
 	(void)__db_mutex_unlock(&txn_region->hdr.lock, fd);
@@ -140,7 +130,6 @@ __txn_create(dbenv, path, mode)
 		(void)txn_unlink(path, 1 /* force */, dbenv);
 		return (ret);
 	}
-
 	return (0);
 }
 
@@ -199,7 +188,7 @@ retry1:	if ((ret = __db_ropen(dbenv, DB_APP_NONE, path, DEFAULT_TXN_FILE,
 
 	/* Now, create the transaction manager structure and set its fields. */
 	if ((tmgrp = (DB_TXNMGR *)malloc(sizeof(DB_TXNMGR))) == NULL) {
-		__db_err(dbenv, "txn_open: %s", strerror(errno));
+		__db_err(dbenv, "txn_open: %s", strerror(ENOMEM));
 		ret = ENOMEM;
 		goto out;
 	}
@@ -211,9 +200,18 @@ retry1:	if ((ret = __db_ropen(dbenv, DB_APP_NONE, path, DEFAULT_TXN_FILE,
 	tmgrp->reg_size = txn_regionp->hdr.size;
 	tmgrp->fd = fd;
 	tmgrp->flags = LF_ISSET(DB_TXN_NOSYNC | DB_THREAD);
+	tmgrp->mem = &txn_regionp[1];
+	tmgrp->mutexp = NULL;
 	TAILQ_INIT(&tmgrp->txn_chain);
-	if (LF_ISSET(DB_THREAD))
-		__db_mutex_init(&tmgrp->mutex, -1);
+	if (LF_ISSET(DB_THREAD)) {
+		LOCK_TXNREGION(tmgrp);
+		if ((ret = __db_shalloc(tmgrp->mem, sizeof(db_mutex_t), 
+		    MUTEX_ALIGNMENT, &tmgrp->mutexp)) == 0)
+			__db_mutex_init(tmgrp->mutexp, -1);
+		UNLOCK_TXNREGION(tmgrp);
+		if (ret != 0)
+			goto out;
+	}
 	*mgrpp = tmgrp;
 	return (0);
 
@@ -221,8 +219,14 @@ out:	if (txn_regionp != NULL)
 		(void)__db_rclose(dbenv, fd, txn_regionp);
 	if (flags & DB_CREATE)
 		(void)txn_unlink(path, 1, dbenv);
-	if (tmgrp != NULL)
+	if (tmgrp != NULL) {
+		if (tmgrp->mutexp != NULL) {
+			LOCK_TXNREGION(tmgrp);
+			__db_shalloc_free(tmgrp->mem, tmgrp->mutexp);
+			UNLOCK_TXNREGION(tmgrp);
+		}
 		free(tmgrp);
+	}
 	return (ret);
 }
 
@@ -239,30 +243,20 @@ txn_begin(tmgrp, parent, txnpp)
 {
 	TXN_DETAIL *txnp;
 	DB_TXN *retp;
-	int id, index, ret;
+	int id, ret;
 
 	LOCK_TXNREGION(tmgrp);
 
-	if ((ret = __txn_validate_region(tmgrp)) != 0) {
-		UNLOCK_TXNREGION(tmgrp);
-		return (ret);
-	}
-
-	/* Remove element from free list. */
-	if (tmgrp->region->free_txn == TXN_INVALID &&
-	    (ret = __txn_grow_region(tmgrp)) != 0) {
-		UNLOCK_TXNREGION(tmgrp);
-		return (ret);
-	}
-
-	index = tmgrp->region->free_txn;
-	txnp = &tmgrp->region->table[index];
-	tmgrp->region->free_txn = txnp->txnid;
+	if ((ret = __txn_validate_region(tmgrp)) != 0)
+		goto err;
 
-	if (txnp->status != TXN_UNALLOC) {
-		UNLOCK_TXNREGION(tmgrp);
-		return (EINVAL);
-	}
+	/* Allocate a new transaction detail structure. */
+	if ((ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp)) != 0
+	    && ret == ENOMEM && (ret = __txn_grow_region(tmgrp)) == 0)
+	    	ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp);
+		
+	if (ret != 0)
+		goto err;
 
 	/* Make sure that last_txnid is not going to wrap around. */
 	if (tmgrp->region->last_txnid == TXN_INVALID)
@@ -270,18 +264,20 @@ txn_begin(tmgrp, parent, txnpp)
 
 	if ((retp = (DB_TXN *)malloc(sizeof(DB_TXN))) == NULL) {
 		__db_err(tmgrp->dbenv, "txn_begin : %s", strerror(ENOMEM));
-		UNLOCK_TXNREGION(tmgrp);
-		return (ENOMEM);
+		ret = ENOMEM;
+		goto err1;
 	}
 
 	id = ++tmgrp->region->last_txnid;
 	tmgrp->region->nbegins++;
 
 	txnp->txnid = id;
-	txnp->last_lock = 0;
-	txnp->status = TXN_RUNNING;
 	ZERO_LSN(txnp->last_lsn);
 	ZERO_LSN(txnp->begin_lsn);
+	txnp->last_lock = 0;
+	txnp->status = TXN_RUNNING;
+	SH_TAILQ_INSERT_HEAD(&tmgrp->region->active_txn,
+	    txnp, links, __txn_detail);
 
 	UNLOCK_TXNREGION(tmgrp);
 
@@ -297,8 +293,9 @@ txn_begin(tmgrp, parent, txnpp)
 
 		/* Deallocate transaction. */
 		LOCK_TXNREGION(tmgrp);
-		txnp->txnid = tmgrp->region->free_txn;
-		tmgrp->region->free_txn = txnp - &tmgrp->region->table[0];
+		SH_TAILQ_REMOVE(&tmgrp->region->active_txn,
+		    txnp, links, __txn_detail);
+		__db_shalloc_free(tmgrp->mem, txnp);
 		UNLOCK_TXNREGION(tmgrp);
 		free (retp);
 		return (ret);
@@ -310,6 +307,12 @@ txn_begin(tmgrp, parent, txnpp)
 
 	*txnpp  = retp;
 	return (0);
+
+err1:
+	__db_shalloc_free(tmgrp->mem, txnp);
+err:
+	UNLOCK_TXNREGION(tmgrp);
+	return (ret);
 }
 
 /* The db_txn(3) man page describes txn_commit. */
@@ -362,16 +365,15 @@ txn_prepare(txnp)
 	int ret;
 	TXN_DETAIL *tp;
 
-	ret = 0;
 	if ((ret = __txn_check_running(txnp)) != 0)
 		return (ret);
 
-	if (txnp->mgrp->dbenv->lg_info) {
-		ret = log_flush(txnp->mgrp->dbenv->lg_info, &txnp->last_lsn);
-		if (ret)
+	if (txnp->mgrp->dbenv->lg_info != NULL) {
+		if ((ret = log_flush(txnp->mgrp->dbenv->lg_info,
+		    &txnp->last_lsn)) != 0)
 			__db_err(txnp->mgrp->dbenv,
 			    "txn_prepare: log_flush failed %s\n",
-			    strerror(errno));
+			    strerror(ret));
 		return (ret);
 	}
 
@@ -420,12 +422,19 @@ txn_close(tmgrp)
 	    ret == 0)
 		ret = t_ret;
 
+	if (tmgrp->mutexp != NULL) {
+		LOCK_TXNREGION(tmgrp);
+		__db_shalloc_free(tmgrp->mem, tmgrp->mutexp);
+		UNLOCK_TXNREGION(tmgrp);
+	}
+
 	if ((t_ret = __db_rclose(tmgrp->dbenv, tmgrp->fd, tmgrp->region)) != 0
 	    && ret == 0)
 		ret = t_ret;
 
 	if (ret == 0)
 		free (tmgrp);
+
 	return (ret);
 }
 
@@ -499,9 +508,8 @@ __txn_end(txnp, is_commit)
 	/* End the transaction. */
 	LOCK_TXNREGION(mgr);
 	tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + txnp->off);
-	tp->status = TXN_UNALLOC;
-	tp->txnid = mgr->region->free_txn;
-	mgr->region->free_txn = tp - &mgr->region->table[0];
+	SH_TAILQ_REMOVE(&mgr->region->active_txn, tp, links, __txn_detail);
+	__db_shalloc_free(mgr->mem, tp);
 	if (is_commit)
 		mgr->region->ncommits++;
 	else
@@ -515,8 +523,9 @@ __txn_end(txnp, is_commit)
 
 
 /*
- * Undo the transaction with id txnid.  Returns 0 on success and sets
- * errno and returns -1 on failure.
+ * __txn_undo --
+ *	Undo the transaction with id txnid.  Returns 0 on success and
+ *	errno on failure.
  */
 static int
 __txn_undo(txnp)
@@ -576,12 +585,12 @@ __txn_undo(txnp)
 int
 txn_checkpoint(mgr, kbytes, minutes)
 	const DB_TXNMGR *mgr;
-	long kbytes, minutes;
+	int kbytes, minutes;
 {
 	TXN_DETAIL *txnp;
 	DB_LSN ckp_lsn, last_ckp;
 	DB_LOG *dblp;
-	u_int32_t bytes_written, i;
+	u_int32_t bytes_written;
 	time_t last_ckp_time, now;
 	int ret;
 
@@ -638,16 +647,16 @@ do_ckp:
 	if (!IS_ZERO_LSN(mgr->region->pending_ckp))
 		ckp_lsn = mgr->region->pending_ckp;
 	else
-		for (txnp = &mgr->region->table[0], i = 0;
-		    i < mgr->region->maxtxns; i++, txnp++) {
+		for (txnp =
+		    SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail);
+		    txnp != NULL;
+		    txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) {
 
 			/*
-			 * Look through the transaction table for the LSN of
-			 * the transaction that is in-use (e.g., not
-			 * TXN_UNALLOC) and whose begin lsn is the lowest.
+			 * Look through the active transactions for the
+			 * lowest begin lsn.
 			 */
-			if (txnp->status != TXN_UNALLOC &&
-			    !IS_ZERO_LSN(txnp->begin_lsn) &&
+			if (!IS_ZERO_LSN(txnp->begin_lsn) &&
 			    log_compare(&txnp->begin_lsn, &ckp_lsn) < 0)
 				ckp_lsn = txnp->begin_lsn;
 		}
@@ -707,6 +716,7 @@ __txn_validate_region(tp)
 		return (ret);
 
 	tp->reg_size = tp->region->hdr.size;
+	tp->mem = &tp->region[1];
 
 	return (0);
 }
@@ -715,9 +725,9 @@ static int
 __txn_grow_region(tp)
 	DB_TXNMGR *tp;
 {
-	TXN_DETAIL *tx;
 	size_t incr;
-	u_int32_t i, oldmax;
+	u_int32_t oldmax;
+	u_int8_t *curaddr;
 	int ret;
 
 	oldmax = tp->region->maxtxns;
@@ -729,19 +739,17 @@ __txn_grow_region(tp)
 	if ((ret = __db_rremap(tp->dbenv, tp->region,
 	    tp->reg_size, tp->reg_size + incr, tp->fd, &tp->region)) != 0)
 		return (ret);
+
+	/* Throw the new space on the free list. */
+	curaddr = (u_int8_t *)tp->region + tp->reg_size;
+	tp->mem = &tp->region[1];
 	tp->reg_size += incr;
 
-	/*
-	 * Initialize all the new transactions and up the transaction count.
-	 */
-	for (i = 0, tx = &tp->region->table[oldmax]; i < oldmax; i++, tx++) {
-		ZERO_LSN(tx->begin_lsn);
-		tx->status = TXN_UNALLOC;
-		tx->txnid = oldmax + i + 1;
-	}
-	tp->region->free_txn = oldmax;
+	*((size_t *)curaddr) = incr - sizeof(size_t);
+	curaddr += sizeof(size_t);
+	__db_shalloc_free(tp->mem, curaddr);
+
 	tp->region->maxtxns = 2 * oldmax;
-	tp->region->table[tp->region->maxtxns - 1].txnid = TXN_INVALID;
 
 	return (0);
 }
@@ -753,8 +761,9 @@ txn_stat(mgr, statp, db_malloc)
 	void *(*db_malloc) __P((size_t));
 {
 	DB_TXN_STAT *stats;
+	TXN_DETAIL *txnp;
 	size_t nbytes;
-	u_int32_t i, nactive, ndx;
+	u_int32_t nactive, ndx;
 
 	LOCK_TXNREGION(mgr);
 	nactive = mgr->region->nbegins -
@@ -789,17 +798,17 @@ txn_stat(mgr, statp, db_malloc)
 		stats->st_nactive = nactive + 200;
 	stats->st_txnarray = (DB_TXN_ACTIVE *)&stats[1];
 
-	for (ndx = 0, i = 0; i < mgr->region->maxtxns; i++)
-		if (mgr->region->table[i].status != TXN_UNALLOC) {
-			stats->st_txnarray[ndx].txnid =
-			    mgr->region->table[i].txnid;
-			stats->st_txnarray[ndx].lsn =
-			    mgr->region->table[i].begin_lsn;
-			ndx++;
+	ndx = 0;
+	for (txnp = SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail);
+	    txnp != NULL;
+	    txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) {
+		stats->st_txnarray[ndx].txnid = txnp->txnid;
+		stats->st_txnarray[ndx].lsn = txnp->begin_lsn;
+		ndx++;
 
-			if (ndx >= stats->st_nactive)
-				break;
-		}
+		if (ndx >= stats->st_nactive)
+			break;
+	}
 
 	UNLOCK_TXNREGION(mgr);
 	*statp = stats;
diff --git a/db2/txn/txn_auto.c b/db2/txn/txn_auto.c
index c7f277ed0f..baef7333c7 100644
--- a/db2/txn/txn_auto.c
+++ b/db2/txn/txn_auto.c
@@ -92,7 +92,7 @@ __txn_regop_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __txn_regop_read(dbtp->data, &argp)) != 0)
+	if ((ret = __txn_regop_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]txn_regop: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
@@ -221,7 +221,7 @@ __txn_ckp_print(notused1, dbtp, lsnp, notused3, notused4)
 	notused3 = 0;
 	notused4 = NULL;
 
-	if((ret = __txn_ckp_read(dbtp->data, &argp)) != 0)
+	if ((ret = __txn_ckp_read(dbtp->data, &argp)) != 0)
 		return (ret);
 	printf("[%lu][%lu]txn_ckp: rec: %lu txnid %lx prevlsn [%lu][%lu]\n",
 	    (u_long)lsnp->file,
diff --git a/elf/link.h b/elf/link.h
index c4b0a4fd9c..c74e240492 100644
--- a/elf/link.h
+++ b/elf/link.h
@@ -111,6 +111,14 @@ struct r_search_path_elem
   };
 
 
+/* A data structure for a simple single linked list of strings.  */
+struct libname_list
+  {
+    const char *name;		/* Name requested (before search).  */
+    struct libname_list *next;	/* Link to next name for this object.  */
+  };
+
+
 /* Structure describing a loaded shared object.  The `l_next' and `l_prev'
    members form a chain of all the shared objects loaded at startup.
 
@@ -130,11 +138,7 @@ struct link_map
     /* All following members are internal to the dynamic linker.
        They may change without notice.  */
 
-    struct libname_list
-      {
-	const char *name;	/* Name requested (before search).  */
-	struct libname_list *next; /* Link to next name for this object.  */
-      } *l_libname;
+    struct libname_list  *l_libname;
     /* Indexed pointers to dynamic section.
        [0,DT_NUM) are indexed by the processor-independent tags.
        [DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC.
diff --git a/elf/sofini.c b/elf/sofini.c
index 6da0062d06..077399f0ce 100644
--- a/elf/sofini.c
+++ b/elf/sofini.c
@@ -13,7 +13,7 @@ static void (*const __DTOR_END__[1]) (void)
    this would be the 'length' field in a real FDE.  */
 
 typedef unsigned int ui32 __attribute__ ((mode (SI)));
-static const ui32 __FRAME_END__[1]
+static ui32 __FRAME_END__[1]
      __attribute__ ((unused, section (".eh_frame")))
      = { 0 };
 #endif
diff --git a/elf/soinit.c b/elf/soinit.c
index 0c3f5b3163..2b333b7ace 100644
--- a/elf/soinit.c
+++ b/elf/soinit.c
@@ -18,7 +18,7 @@ run_hooks (void (*const list[]) (void))
 }
 
 #ifdef HAVE_DWARF2_UNWIND_INFO
-static const char __EH_FRAME_BEGIN__[]
+static char __EH_FRAME_BEGIN__[]
      __attribute__ ((section (".eh_frame")))
      = { };
 extern void __register_frame (const void *);
diff --git a/include/features.h b/include/features.h
index d1f4ae3d29..52aeaabb4c 100644
--- a/include/features.h
+++ b/include/features.h
@@ -27,7 +27,8 @@
    _POSIX_SOURCE	IEEE Std 1003.1.
    _POSIX_C_SOURCE	If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2;
 			if >=199309L, add IEEE Std 1003.1b-1993
-   _XOPEN_SOURCE	Includes POSIX and XPG things.
+   _XOPEN_SOURCE	Includes POSIX and XPG things.  Set to 500 if
+			Single Unix conformance is wanted.
    _XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions.
    _BSD_SOURCE		ISO C, POSIX, and 4.3BSD things.
    _SVID_SOURCE		ISO C, POSIX, and SVID things.
@@ -50,6 +51,7 @@
    __USE_POSIX199309	Define IEEE Std 1003.1b things.
    __USE_XOPEN		Define XPG things.
    __USE_XOPEN_EXTENDED	Define X/Open Unix things.
+   __USE_UNIX98		Define Single Unix V2 things.
    __USE_BSD		Define 4.3BSD things.
    __USE_SVID		Define SVID things.
    __USE_MISC		Define things common to BSD and System V Unix.
@@ -111,7 +113,7 @@
 # undef  _POSIX_C_SOURCE
 # define _POSIX_C_SOURCE	199309L
 # undef  _XOPEN_SOURCE
-# define _XOPEN_SOURCE	1
+# define _XOPEN_SOURCE	500
 # undef  _XOPEN_SOURCE_EXTENDED
 # define _XOPEN_SOURCE_EXTENDED	1
 # undef  _BSD_SOURCE
@@ -141,7 +143,7 @@
 #if (!defined __STRICT_ANSI__ && !defined _POSIX_SOURCE && \
      !defined _POSIX_C_SOURCE)
 # define _POSIX_SOURCE	1
-# ifdef _XOPEN_SOURCE
+# if defined _XOPEN_SOURCE && _XOPEN_SOURCE != 500
 #  define _POSIX_C_SOURCE	2
 # else
 #  define _POSIX_C_SOURCE	199309L
@@ -162,8 +164,13 @@
 
 #ifdef	_XOPEN_SOURCE
 # define __USE_XOPEN	1
-# ifdef _XOPEN_SOURCE_EXTENDED
+# if _XOPEN_SOURCE == 500
 #  define __USE_XOPEN_EXTENDED	1
+#  define __USE_UNIX98	1
+# else
+#  ifdef _XOPEN_SOURCE_EXTENDED
+#   define __USE_XOPEN_EXTENDED	1
+#  endif
 # endif
 #endif
 
diff --git a/intl/dcgettext.c b/intl/dcgettext.c
index ecc2e1ac26..692ce45bcf 100644
--- a/intl/dcgettext.c
+++ b/intl/dcgettext.c
@@ -597,3 +597,28 @@ stpcpy (dest, src)
   return dest - 1;
 }
 #endif
+
+
+#ifdef _LIBC
+/* If we want to free all resources we have to do some work at
+   program's end.  */
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  struct binding *runp;
+
+  for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next)
+    {
+      free (runp->domainname);
+      if (runp->dirname != _nl_default_dirname)
+	/* Yes, this is a pointer comparison.  */
+	free (runp->dirname);
+    }
+
+  if (_nl_current_default_domain != _nl_default_default_domain)
+    /* Yes, again a pointer comparison.  */
+    free ((char *) _nl_current_default_domain);
+}
+
+text_set_element (__libc_subfreeres, free_mem);
+#endif
diff --git a/intl/finddomain.c b/intl/finddomain.c
index 769bd93eee..a44197c808 100644
--- a/intl/finddomain.c
+++ b/intl/finddomain.c
@@ -197,3 +197,23 @@ _nl_find_domain (dirname, locale, domainname)
 
   return retval;
 }
+
+
+#ifdef _LIBC
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  struct loaded_l10nfile *runp = _nl_loaded_domains;
+
+  while (runp != NULL)
+    {
+      struct loaded_l10nfile *here = runp;
+      if (runp->data != NULL)
+	_nl_unload_domain ((struct loaded_domain *) runp->data);
+      runp = runp->next;
+      free (here);
+    }
+}
+
+text_set_element (__libc_subfreeres, free_mem);
+#endif
diff --git a/intl/gettextP.h b/intl/gettextP.h
index 8a4560dbfd..5225bcbc5e 100644
--- a/intl/gettextP.h
+++ b/intl/gettextP.h
@@ -50,6 +50,8 @@ SWAP (i)
 struct loaded_domain
 {
   const char *data;
+  int use_mmap;
+  size_t mmap_size;
   int must_swap;
   nls_uint32 nstrings;
   struct string_desc *orig_tab;
@@ -69,6 +71,7 @@ struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
 						 char *__locale,
 						 const char *__domainname));
 void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
+void _nl_unload_domain PARAMS ((struct loaded_domain *__domain));
 
 /* @@ begin of epilog @@ */
 
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index f4352d00eb..43158c4cfa 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -168,6 +168,8 @@ _nl_load_domain (domain_file)
 
   domain = (struct loaded_domain *) domain_file->data;
   domain->data = (char *) data;
+  domain->use_mmap = use_mmap;
+  domain->mmap_size = st.st_size;
   domain->must_swap = data->magic != _MAGIC;
 
   /* Fill in the information about the available tables.  */
@@ -201,3 +203,18 @@ _nl_load_domain (domain_file)
      translations invalid.  */
   ++_nl_msg_cat_cntr;
 }
+
+
+#ifdef _LIBC
+void
+_nl_unload_domain (domain)
+     struct loaded_domain *domain;
+{
+  if (domain->use_mmap)
+    munmap ((caddr_t) domain->data, domain->mmap_size);
+  else
+    free ((void *) domain->data);
+
+  free (domain);
+}
+#endif
diff --git a/intl/localealias.c b/intl/localealias.c
index c77f12527e..46d570f88f 100644
--- a/intl/localealias.c
+++ b/intl/localealias.c
@@ -134,6 +134,9 @@ struct alias_map
 };
 
 
+static char *string_space = NULL;
+static size_t string_space_act = 0;
+static size_t string_space_max = 0;
 static struct alias_map *map;
 static size_t nmap = 0;
 static size_t maxmap = 0;
@@ -272,7 +275,8 @@ read_alias_file (fname, fname_len)
 	  if (cp[0] != '\0')
 	    {
 	      char *tp;
-	      size_t len;
+	      size_t alias_len;
+	      size_t value_len;
 
 	      value = cp++;
 	      while (cp[0] != '\0' && !isspace (cp[0]))
@@ -292,35 +296,32 @@ read_alias_file (fname, fname_len)
 	      if (nmap >= maxmap)
 		extend_alias_table ();
 
-#if defined _LIBC || defined HAVE_STRDUP
-	       map[nmap].alias = strdup (alias);
-	       map[nmap].value = strdup (value);
-	       if (map[nmap].alias == NULL || map[nmap].value == NULL)
-		{
-		  FREE_BLOCKS (block_list);
-		  return added;
-		}
-#else
-	      len = strlen (alias) + 1;
-	      tp = (char *) malloc (len);
-	      if (tp == NULL)
-		{
-		  FREE_BLOCKS (block_list);
-		  return added;
-		}
-	      memcpy (tp, alias, len);
-	      map[nmap].alias = tp;
+	      alias_len = strlen (alias) + 1;
+	      value_len = strlen (value) + 1;
 
-	      len = strlen (value) + 1;
-	      tp = (char *) malloc (len);
-	      if (tp == NULL)
+	      if (string_space_act + alias_len + value_len > string_space_max)
 		{
-		  FREE_BLOCKS (block_list);
-		  return added;
+		  /* Increase size of memory pool.  */
+		  size_t new_size = (string_space_max
+				     + (alias_len + value_len > 1024
+					? alias_len + value_len : 1024));
+		  char *new_pool = (char *) realloc (string_space, new_size);
+		  if (new_pool == NULL)
+		    {
+		      FREE_BLOCKS (block_list);
+		      return added;
+		    }
+		  string_space = new_pool;
+		  string_space_max = new_size;
 		}
-	      memcpy (tp, value, len);
-	      map[nmap].value = tp;
-#endif
+
+	      map[nmap].alias = memcpy (&string_space[string_space_act],
+					alias, alias_len);
+	      string_space_act += alias_len;
+
+	      map[nmap].alias = memcpy (&string_space[string_space_act],
+					value, value_len);
+	      string_space_act += value_len;
 
 	      ++nmap;
 	      ++added;
@@ -359,22 +360,30 @@ extend_alias_table ()
   struct alias_map *new_map;
 
   new_size = maxmap == 0 ? 100 : 2 * maxmap;
-  new_map = (struct alias_map *) malloc (new_size
-					 * sizeof (struct alias_map));
+  new_map = (struct alias_map *) realloc (map, (new_size
+						* sizeof (struct alias_map)));
   if (new_map == NULL)
     /* Simply don't extend: we don't have any more core.  */
     return;
 
-  memcpy (new_map, map, nmap * sizeof (struct alias_map));
-
-  if (maxmap != 0)
-    free (map);
-
   map = new_map;
   maxmap = new_size;
 }
 
 
+#ifdef _LIBC
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  if (string_space != NULL)
+    free (string_space);
+  if (map != NULL)
+    free (map);
+}
+text_set_element (__libc_subfreeres, free_mem);
+#endif
+
+
 static int
 alias_compare (map1, map2)
      const struct alias_map *map1;
diff --git a/libc.map b/libc.map
index c83fb38b22..0abd31d5a1 100644
--- a/libc.map
+++ b/libc.map
@@ -177,9 +177,9 @@ GLIBC_2.0 {
     fgetspent; fgetspent_r; fileno; fileno_unlocked; finite; finitef;
     finitel; flock; flockfile; fmtmsg; fnmatch; fopen; fopencookie; fork;
     fpathconf; fprintf; fputc; fputc_unlocked; fputs; fread; free;
-    freeaddrinfo; freopen; frexp; frexpf; frexpl; fscanf; fseek; fsetpos;
-    fstatfs; fsync; ftell; ftime; ftok; ftruncate; ftrylockfile;
-    fts_children; fts_close; fts_open; fts_read; fts_set; ftw;
+    freeaddrinfo; freopen; frexp; frexpf; frexpl; fscanf; fseek; fseeko;
+    fsetpos; fstatfs; fsync; ftell; ftello; ftime; ftok; ftruncate;
+    ftrylockfile; fts_children; fts_close; fts_open; fts_read; fts_set; ftw;
     funlockfile; fwrite;
 
     # g*
@@ -276,8 +276,8 @@ GLIBC_2.0 {
     parse_printf_format; passwd2des; pathconf; pause; pciconfig_read;
     pciconfig_write; pclose; perror;
     personality; pipe; pmap_getmaps; pmap_getport; pmap_rmtcall; pmap_set;
-    pmap_unset; poll; popen; printf; printf_size; printf_size_info;
-    profil; profil_counter; pselect; psignal;
+    pmap_unset; poll; popen; pread; printf; printf_size; printf_size_info;
+    profil; profil_counter; pwrite; pselect; psignal;
 
     pthread_attr_destroy;
     pthread_attr_getdetachstate; pthread_attr_getinheritsched;
diff --git a/libio/Makefile b/libio/Makefile
index e24e6ff66a..aea60f5226 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -32,7 +32,7 @@ routines	:=							      \
 									      \
 	clearerr feof ferror fgetc fileno fputc freopen fseek getc getchar    \
 	memstream pclose putc putchar rewind setbuf setlinebuf vasprintf      \
-	iovdprintf vscanf vsnprintf obprintf fcloseall			      \
+	iovdprintf vscanf vsnprintf obprintf fcloseall fseeko ftello	      \
 									      \
 	libc_fatal
 
diff --git a/libio/fseeko.c b/libio/fseeko.c
new file mode 100644
index 0000000000..0ebdfa937e
--- /dev/null
+++ b/libio/fseeko.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
+
+   This library is free software; you can redistribute 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 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include "libioP.h"
+#include "stdio.h"
+
+int
+fseeko (fp, offset, whence)
+     _IO_FILE* fp;
+     off_t offset;
+     int whence;
+{
+  int result;
+  CHECK_FILE (fp, -1);
+  _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+  _IO_flockfile (fp);
+  result = _IO_fseek (fp, offset, whence);
+  _IO_cleanup_region_end (1);
+  return result;
+}
diff --git a/libio/ftello.c b/libio/ftello.c
new file mode 100644
index 0000000000..7585eea9ec
--- /dev/null
+++ b/libio/ftello.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU IO Library.
+
+   This library is free software; you can redistribute 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 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this library; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+   As a special exception, if you link this library with files
+   compiled with a GNU compiler to produce an executable, this does
+   not cause the resulting executable to be covered by the GNU General
+   Public License.  This exception does not however invalidate any
+   other reasons why the executable file might be covered by the GNU
+   General Public License.  */
+
+#include <stdio.h>
+#include <libioP.h>
+#include <errno.h>
+
+
+off_t
+ftello (fp)
+     _IO_FILE *fp;
+{
+  _IO_pos_t pos;
+  CHECK_FILE (fp, -1L);
+  _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+  _IO_flockfile (fp);
+  pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
+  _IO_cleanup_region_end (1);
+  if (pos == _IO_pos_BAD)
+    {
+#ifdef EIO
+      if (errno == 0)
+	__set_errno (EIO);
+#endif
+      return -1L;
+    }
+  return _IO_pos_as_off (pos);
+}
diff --git a/libio/stdio.h b/libio/stdio.h
index d941aba23b..bbed294056 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -496,6 +496,17 @@ extern long int ftell __P ((FILE *__stream));
 /* Rewind to the beginning of STREAM.  */
 extern void rewind __P ((FILE *__stream));
 
+#ifdef __USE_UNIX98
+/* The Single Unix Specification, Version 2, specifies an alternative,
+   more adequate interface for the two functions above which deal with
+   file offset.  `long int' is not the right type.  */
+
+/* Seek to a certain position on STREAM.  */
+extern int fseeko __P ((FILE *__stream, __off_t __off, int __whence));
+/* Return the current position of STREAM.  */
+extern __off_t ftello __P ((FILE *__stream));
+#endif
+
 /* Get STREAM's position.  */
 extern int fgetpos __P ((FILE *__restrict __stream,
 			 fpos_t *__restrict __pos));
diff --git a/locale/C-collate.c b/locale/C-collate.c
index 5c049e1f59..ba85002d5c 100644
--- a/locale/C-collate.c
+++ b/locale/C-collate.c
@@ -147,7 +147,7 @@ const struct locale_data _nl_C_LC_COLLATE =
 {
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
-  MAX_USAGE_COUNT,
+  UNDELETABLE,
   21,
   {
     { word: 0 },
diff --git a/locale/C-ctype.c b/locale/C-ctype.c
index 6a1c3fc7be..851b95fd98 100644
--- a/locale/C-ctype.c
+++ b/locale/C-ctype.c
@@ -342,7 +342,7 @@ const struct locale_data _nl_C_LC_CTYPE =
 {
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
-  MAX_USAGE_COUNT,
+  UNDELETABLE,
   15,
   {
     { string: _nl_C_LC_CTYPE_class },
diff --git a/locale/C-messages.c b/locale/C-messages.c
index 70eeb8cc80..0363020476 100644
--- a/locale/C-messages.c
+++ b/locale/C-messages.c
@@ -28,7 +28,7 @@ const struct locale_data _nl_C_LC_MESSAGES =
 {
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
-  MAX_USAGE_COUNT,
+  UNDELETABLE,
   4,
   {
     { string: "^[yY]" },
diff --git a/locale/C-monetary.c b/locale/C-monetary.c
index 8dd361a2e0..0133319740 100644
--- a/locale/C-monetary.c
+++ b/locale/C-monetary.c
@@ -31,7 +31,7 @@ const struct locale_data _nl_C_LC_MONETARY =
 {
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
-  MAX_USAGE_COUNT,
+  UNDELETABLE,
   15,
   {
     { string: "" },
diff --git a/locale/C-numeric.c b/locale/C-numeric.c
index a456214213..d42c5266be 100644
--- a/locale/C-numeric.c
+++ b/locale/C-numeric.c
@@ -31,7 +31,7 @@ const struct locale_data _nl_C_LC_NUMERIC =
 {
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
-  MAX_USAGE_COUNT,
+  UNDELETABLE,
   3,
   {
     { string: "." },
diff --git a/locale/C-time.c b/locale/C-time.c
index 095d097e2b..673d9bd478 100644
--- a/locale/C-time.c
+++ b/locale/C-time.c
@@ -26,7 +26,7 @@ const struct locale_data _nl_C_LC_TIME =
 {
   _nl_C_name,
   NULL, 0, 0, /* no file mapped */
-  MAX_USAGE_COUNT,
+  UNDELETABLE,
   54,
   {
     { string: "Sun" },
diff --git a/locale/findlocale.c b/locale/findlocale.c
index c027968530..b651dbaaad 100644
--- a/locale/findlocale.c
+++ b/locale/findlocale.c
@@ -176,7 +176,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
 
   /* Increment the usage count.  */
   if (((struct locale_data *) locale_file->data)->usage_count
-      != MAX_USAGE_COUNT)
+      < MAX_USAGE_COUNT)
     ++((struct locale_data *) locale_file->data)->usage_count;
 
   return (struct locale_data *) locale_file->data;
@@ -213,7 +213,7 @@ _nl_remove_locale (int locale, struct locale_data *data)
 	     permanent.  */
 	  if (__munmap ((caddr_t) data->filedata, data->filesize) != 0)
 	    {
-	      data->usage_count = MAX_USAGE_COUNT;
+	      data->usage_count = UNDELETABLE;
 	      return;
 	    }
 	}
@@ -225,3 +225,26 @@ _nl_remove_locale (int locale, struct locale_data *data)
       free (data);
     }
 }
+
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  int locale;
+
+  for (locale = 0; locale < LC_ALL; ++locale)
+    {
+      struct loaded_l10nfile *runp = locale_file_list[locale];
+
+      while (runp != NULL)
+	{
+	  struct loaded_l10nfile *here = runp;
+	  struct locale_data *data = (struct locale_data *) runp->data;
+
+	  if (data != NULL && data->usage_count != UNDELETABLE)
+	    _nl_unload_locale (data);
+	  runp = runp->next;
+	  free (here);
+	}
+    }
+}
+text_set_element (__libc_subfreeres, free_mem);
diff --git a/locale/loadlocale.c b/locale/loadlocale.c
index 15570c36d1..3ac161eb3a 100644
--- a/locale/loadlocale.c
+++ b/locale/loadlocale.c
@@ -221,3 +221,14 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
   __close (fd);
   file->data = newdata;
 }
+
+void
+_nl_unload_locale (struct locale_data *locale)
+{
+  if (locale->mmaped)
+    __munmap ((caddr_t) locale->filedata, locale->filesize);
+  else
+    free ((void *) locale->filedata);
+
+  free (locale);
+}
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index 29731fa4c6..f50565c54a 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -38,7 +38,8 @@
 
 /* We use a special value for the usage counter in `locale_data' to
    signal that this data must never be removed anymore.  */
-#define MAX_USAGE_COUNT UINT_MAX
+#define MAX_USAGE_COUNT (UINT_MAX - 1)
+#define UNDELETABLE	UINT_MAX
 
 /* Structure describing locale data in core for a category.  */
 struct locale_data
@@ -135,6 +136,9 @@ extern struct locale_data *_nl_find_locale (const char *locale_path,
 /* Try to load the file described by FILE.  */
 extern void _nl_load_locale (struct loaded_l10nfile *file, int category);
 
+/* Free all resource.  */
+extern void _nl_unload_locale (struct locale_data *locale);
+
 /* Free the locale and give back all memory if the usage count is one.  */
 extern void _nl_remove_locale (int locale, struct locale_data *data);
 
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index 6290274a72..c511d4246c 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -108,7 +108,7 @@ static const struct argp_option options[] =
   { "posix", OPT_POSIX, NULL, 0, N_("Be strictly POSIX conform") },
   { "quiet", OPT_QUIET, NULL, 0,
     N_("Suppress warnings and information messages") },
-  { "verbose", 'V', NULL, 0, N_("Print more messages") },
+  { "verbose", 'v', NULL, 0, N_("Print more messages") },
   { NULL, 0, NULL, 0, NULL }
 };
 
diff --git a/malloc/Makefile b/malloc/Makefile
index addabf12f8..bad756aa64 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -41,6 +41,9 @@ non-lib.a := libmcheck.a
 # These should be removed by `make clean'.
 extra-objs = mcheck-init.o libmcheck.a
 
+# Include the cleanup handler.
+aux := set-freeres
+
 # The AWK script to analyze the output of the mtrace functions.
 ifneq ($(PERL),no)
 install-bin = mtrace
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
index aeefd5600e..54c9dfffbd 100644
--- a/malloc/mtrace.c
+++ b/malloc/mtrace.c
@@ -193,6 +193,23 @@ tr_reallochook (ptr, size, caller)
   return hdr;
 }
 
+
+#ifdef _LIBC
+extern void __libc_freeres (void);
+
+/* This function gets called to make sure all memory the library
+   allocates get freed and so does not irritate the user when studying
+   the mtrace output.  */
+static void
+release_libc_mem (void)
+{
+  /* Only call the free function if we still are running in mtrace mode.  */
+  if (mallstream != NULL)
+    __libc_freeres ();
+}
+#endif
+
+
 /* We enable tracing if either the environment variable MALLOC_TRACE
    is set, or if the variable mallwatch has been patched to an address
    that the debugging user wants us to stop on.  When patching mallwatch,
@@ -201,6 +218,9 @@ tr_reallochook (ptr, size, caller)
 void
 mtrace ()
 {
+#ifdef _LIBC
+  static int added_atexit_handler = 0;
+#endif
   char *mallfile;
 
   /* Don't panic if we're called more than once.  */
@@ -229,6 +249,13 @@ mtrace ()
 	  __malloc_hook = tr_mallochook;
 	  tr_old_realloc_hook = __realloc_hook;
 	  __realloc_hook = tr_reallochook;
+#ifdef _LIBC
+	  if (!added_atexit_handler)
+	    {
+	      added_atexit_handler = 1;
+	      atexit (release_libc_mem);
+	    }
+#endif
 	}
     }
 }
diff --git a/malloc/set-freeres.c b/malloc/set-freeres.c
new file mode 100644
index 0000000000..7efd06e33c
--- /dev/null
+++ b/malloc/set-freeres.c
@@ -0,0 +1,33 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <stdlib.h>
+#include <set-hooks.h>
+
+DEFINE_HOOK (__libc_subfreeres, (void));
+
+void
+__libc_freeres (void)
+{
+  /* This function might be called from different places.  So better
+     protect for multiple executions since these are fatal.  */
+  static int already_called = 0;
+
+  if (!already_called)
+    RUN_HOOK (__libc_subfreeres, ());
+}
diff --git a/manual/creature.texi b/manual/creature.texi
index edac770f6c..9d9b451a94 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -85,6 +85,10 @@ BSD and SVID is also included.
 If the macro @code{_XOPEN_SOURCE_EXTENDED} is also defined, even more
 functionality is available.  The extra functions will make all functions
 available which are necessary for the X/Open Unix brand.
+
+If the macro @code{_XOPEN_SOURCE} has the value @math{500} this includes
+all functionality described so far plus some new definitions from the
+Single Unix specification, @w{version 2}.
 @end defvr
 
 @comment (none)
diff --git a/manual/llio.texi b/manual/llio.texi
index 7891ee66e0..4c10b72578 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -301,6 +301,35 @@ The @code{read} function is the underlying primitive for all of the
 functions that read from streams, such as @code{fgetc}.
 @end deftypefun
 
+@comment unistd.h
+@comment Unix98
+@deftypefun ssize_t pread (int @var{filedes}, void *@var{buffer}, size_t @var{size}, off_t @var{offset})
+The @code{pread} function is similar to the @code{read} function.  The
+first three arguments are identical and also the return values and error
+codes correspond.
+
+The difference is the fourth argument and its handling.  The data block
+is not read from the current position of the file descriptor
+@code{filedes}.  Instead the data is read from the file starting at
+position @var{offset}.  The position of the file descriptor itself is
+not effected by the operation.  The value is the same as before the call.
+
+The return value of @code{pread} describes the number of bytes read.
+In the error case it returns @math{-1} like @code{read} does and the
+error codes are also the same.  Only there are a few more error codes:
+@table @code
+@item EINVAL
+The value given for @var{offset} is negative and therefore illegal.
+
+@item ESPIPE
+The file descriptor @var{filedes} is associate with a pipe or a FIFO and
+this device does not allow positioning of the file pointer.
+@end table
+
+The function is an extension defined in the Unix Single Specification
+version 2.
+@end deftypefun
+
 @cindex writing to a file descriptor
 @comment unistd.h
 @comment POSIX.1
@@ -320,8 +349,10 @@ storage immediately.  You can use @code{fsync} when you need to be sure
 your data has been permanently stored before continuing.  (It is more
 efficient for the system to batch up consecutive writes and do them all
 at once when convenient.  Normally they will always be written to disk
-within a minute or less.)
-@c !!! xref fsync
+within a minute or less.)  Modern systems provide another function
+@code{fdatasync} which guarantees integrity only for the file data and
+is therefore faster.
+@c !!! xref fsync, fdatasync
 You can use the @code{O_FSYNC} open mode to make @code{write} always
 store the data to disk before returning; @pxref{Operating Modes}.
 
@@ -392,6 +423,36 @@ The @code{write} function is the underlying primitive for all of the
 functions that write to streams, such as @code{fputc}.
 @end deftypefun
 
+@comment unistd.h
+@comment Unix98
+@deftypefun ssize_t pwrite (int @var{filedes}, const void *@var{buffer}, size_t @var{size}, off_t @var{offset})
+The @code{pwrite} function is similar to the @code{write} function.  The
+first three arguments are identical and also the return values and error
+codes correspond.
+
+The difference is the fourth argument and its handling.  The data block
+is not written to the current position of the file descriptor
+@code{filedes}.  Instead the data is written to the file starting at
+position @var{offset}.  The position of the file descriptor itself is
+not effected by the operation.  The value is the same as before the call.
+
+The return value of @code{pwrite} describes the number of written bytes.
+In the error case it returns @math{-1} like @code{write} does and the
+error codes are also the same.  Only there are a few more error codes:
+@table @code
+@item EINVAL
+The value given for @var{offset} is negative and therefore illegal.
+
+@item ESPIPE
+The file descriptor @var{filedes} is associate with a pipe or a FIFO and
+this device does not allow positioning of the file pointer.
+@end table
+
+The function is an extension defined in the Unix Single Specification
+version 2.
+@end deftypefun
+
+
 @node File Position Primitive
 @section Setting the File Position of a Descriptor
 
diff --git a/manual/stdio.texi b/manual/stdio.texi
index 085a1c95a8..4c90b25447 100644
--- a/manual/stdio.texi
+++ b/manual/stdio.texi
@@ -697,8 +697,9 @@ order that they were pushed.
 
 Pushing back characters doesn't alter the file; only the internal
 buffering for the stream is affected.  If a file positioning function
-(such as @code{fseek} or @code{rewind}; @pxref{File Positioning}) is
-called, any pending pushed-back characters are discarded.
+(such as @code{fseek}, @code{fseeko} or @code{rewind}; @pxref{File
+Positioning}) is called, any pending pushed-back characters are
+discarded.
 
 Unreading a character on a stream that is at end of file clears the
 end-of-file indicator for the stream, because it makes the character of
@@ -3033,6 +3034,28 @@ possibly for other reasons as well.  If a failure occurs, a value of
 @end deftypefun
 
 @comment stdio.h
+@comment Unix98
+@deftypefun off_t ftello (FILE *@var{stream})
+The @code{ftello} function is similar to @code{ftell} only it corrects a
+problem which the POSIX type system.  In this type system all file
+positions are described using values of type @code{off_t} which is not
+necessarily of the same size as @code{long int}.  Therefore using
+@code{ftell} can lead to problems if the implementation is written on
+top of a POSIX compliant lowlevel I/O implementation.
+
+Therefore it is a good idea to prefer @code{ftello} whenever it is
+available since its functionality is (if different at all) closer the
+underlying definition.
+
+If this function fails it return @code{(off_t) -1}.  This can happen due
+to missing support for file positioning or internal errors.  Otherwise
+the return value is the current file position.
+
+The function is an extension defined in the Unix Single Specification
+version 2.
+@end deftypefun
+
+@comment stdio.h
 @comment ISO
 @deftypefun int fseek (FILE *@var{stream}, long int @var{offset}, int @var{whence})
 The @code{fseek} function is used to change the file position of the
@@ -3051,9 +3074,28 @@ position or else remembers it so it will be written later in its proper
 place in the file.
 @end deftypefun
 
-@strong{Portability Note:} In non-POSIX systems, @code{ftell} and
-@code{fseek} might work reliably only on binary streams.  @xref{Binary
-Streams}.
+@comment stdio.h
+@comment Unix98
+@deftypefun int fseeko (FILE *@var{stream}, off_t @var{offset}, int @var{whence})
+This function is similar to @code{fseek} but it corrects a problem with
+@code{fseek} in a system with POSIX types.  Using a value of type
+@code{long int} for the offset is not compatible with POSIX.
+@code{fseeko} uses the correct type @code{off_t} for the @var{offset}
+parameter.
+
+For this reasonit is a good idea to prefer @code{ftello} whenever it is
+available since its functionality is (if different at all) closer the
+underlying definition.
+
+The functionality and return value is the same as for @code{fseek}.
+
+The function is an extension defined in the Unix Single Specification
+version 2.
+@end deftypefun
+
+@strong{Portability Note:} In non-POSIX systems, @code{ftell},
+@code{ftello}, @code{fseek} and @code{fseeko} might work reliably only
+on binary streams.  @xref{Binary Streams}.
 
 The following symbolic constants are defined for use as the @var{whence}
 argument to @code{fseek}.  They are also used with the @code{lseek}
@@ -3064,34 +3106,35 @@ function (@pxref{I/O Primitives}) and to specify offsets for file locks
 @comment ISO
 @deftypevr Macro int SEEK_SET
 This is an integer constant which, when used as the @var{whence}
-argument to the @code{fseek} function, specifies that the offset
-provided is relative to the beginning of the file.
+argument to the @code{fseek} or @code{fseeko} function, specifies that
+the offset provided is relative to the beginning of the file.
 @end deftypevr
 
 @comment stdio.h
 @comment ISO
 @deftypevr Macro int SEEK_CUR
 This is an integer constant which, when used as the @var{whence}
-argument to the @code{fseek} function, specifies that the offset
-provided is relative to the current file position.
+argument to the @code{fseek} or @code{fseeko} function, specifies that
+the offset provided is relative to the current file position.
 @end deftypevr
 
 @comment stdio.h
 @comment ISO
 @deftypevr Macro int SEEK_END
 This is an integer constant which, when used as the @var{whence}
-argument to the @code{fseek} function, specifies that the offset
-provided is relative to the end of the file.
+argument to the @code{fseek} or @code{fseeko} function, specifies that
+the offset provided is relative to the end of the file.
 @end deftypevr
 
 @comment stdio.h
 @comment ISO
 @deftypefun void rewind (FILE *@var{stream})
 The @code{rewind} function positions the stream @var{stream} at the
-begining of the file.  It is equivalent to calling @code{fseek} on the
-@var{stream} with an @var{offset} argument of @code{0L} and a
-@var{whence} argument of @code{SEEK_SET}, except that the return
-value is discarded and the error indicator for the stream is reset.
+begining of the file.  It is equivalent to calling @code{fseek} or
+@code{fseeko} on the @var{stream} with an @var{offset} argument of
+@code{0L} and a @var{whence} argument of @code{SEEK_SET}, except that
+the return value is discarded and the error indicator for the stream is
+reset.
 @end deftypefun
 
 These three aliases for the @samp{SEEK_@dots{}} constants exist for the
@@ -3122,9 +3165,10 @@ An alias for @code{SEEK_END}.
 @section Portable File-Position Functions
 
 On the GNU system, the file position is truly a character count.  You
-can specify any character count value as an argument to @code{fseek} and
-get reliable results for any random access file.  However, some @w{ISO C}
-systems do not represent file positions in this way.
+can specify any character count value as an argument to @code{fseek} or
+@code{fseeko} and get reliable results for any random access file.
+However, some @w{ISO C} systems do not represent file positions in this
+way.
 
 On some systems where text streams truly differ from binary streams, it
 is impossible to represent the file position of a text stream as a count
@@ -3140,14 +3184,14 @@ systems, you must observe certain rules:
 The value returned from @code{ftell} on a text stream has no predictable
 relationship to the number of characters you have read so far.  The only
 thing you can rely on is that you can use it subsequently as the
-@var{offset} argument to @code{fseek} to move back to the same file
-position.
+@var{offset} argument to @code{fseek} or @code{fseeko} to move back to
+the same file position.
 
 @item
-In a call to @code{fseek} on a text stream, either the @var{offset} must
-either be zero; or @var{whence} must be @code{SEEK_SET} and the
-@var{offset} must be the result of an earlier call to @code{ftell} on
-the same stream.
+In a call to @code{fseek} or @code{fseeko} on a text stream, either the
+@var{offset} must either be zero; or @var{whence} must be
+@code{SEEK_SET} and the @var{offset} must be the result of an earlier
+call to @code{ftell} on the same stream.
 
 @item
 The value of the file position indicator of a text stream is undefined
@@ -3158,7 +3202,11 @@ that haven't been read or discarded.  @xref{Unreading}.
 But even if you observe these rules, you may still have trouble for long
 files, because @code{ftell} and @code{fseek} use a @code{long int} value
 to represent the file position.  This type may not have room to encode
-all the file positions in a large file.
+all the file positions in a large file.  Using the @code{ftello} and
+@code{fseeko} functions might help here since the @code{off_t} type is
+expected to be able to hold all file position values but this still does
+not help to handle additional information which must be associated with
+a file position.
 
 So if you do want to support systems with peculiar encodings for the
 file positions, it is better to use the functions @code{fgetpos} and
@@ -3550,9 +3598,10 @@ new values before you use them again.
 A null character is written at the end of the buffer.  This null character
 is @emph{not} included in the size value stored at @var{sizeloc}.
 
-You can move the stream's file position with @code{fseek} (@pxref{File
-Positioning}).  Moving the file position past the end of the data
-already written fills the intervening space with zeroes.
+You can move the stream's file position with @code{fseek} or
+@code{fseeko} (@pxref{File Positioning}).  Moving the file position past
+the end of the data already written fills the intervening space with
+zeroes.
 @end deftypefun
 
 Here is an example of using @code{open_memstream}:
@@ -3587,9 +3636,9 @@ Calling @code{fflush} on this stream updates the current size of the
 object to match the amount of data that has been written.  After a call
 to @code{fflush}, you can examine the object temporarily.
 
-You can move the file position of an obstack stream with @code{fseek}
-(@pxref{File Positioning}).  Moving the file position past the end of
-the data written fills the intervening space with zeros.
+You can move the file position of an obstack stream with @code{fseek} or
+@code{fseeko} (@pxref{File Positioning}).  Moving the file position past
+the end of the data written fills the intervening space with zeros.
 
 To make the object permanent, update the obstack with @code{fflush}, and
 then use @code{obstack_finish} to finalize the object and get its address.
@@ -3691,9 +3740,9 @@ discarded.
 @item cookie_seek_function_t *seek
 This is the function that performs the equivalent of file positioning on
 the cookie.  If the value is a null pointer instead of a function, calls
-to @code{fseek} on this stream can only seek to locations within the
-buffer; any attempt to seek outside the buffer will return an
-@code{ESPIPE} error.
+to @code{fseek} or @code{fseeko} on this stream can only seek to
+locations within the buffer; any attempt to seek outside the buffer will
+return an @code{ESPIPE} error.
 
 @item cookie_close_function_t *close
 This function performs any appropriate cleanup on the cookie when
diff --git a/misc/hsearch.c b/misc/hsearch.c
index f2739b8801..62f8ac9fee 100644
--- a/misc/hsearch.c
+++ b/misc/hsearch.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
    This file is part of the GNU C Library.
 
@@ -50,3 +50,7 @@ hdestroy ()
 {
   hdestroy_r (&htab);
 }
+
+/* Make sure the table is freed if we want to free everything before
+   exiting.  */
+text_set_element (__libc_subfreeres, hdestroy);
diff --git a/misc/sys/select.h b/misc/sys/select.h
index a151570bc6..17edf820aa 100644
--- a/misc/sys/select.h
+++ b/misc/sys/select.h
@@ -52,7 +52,7 @@ typedef __fd_set fd_set;
 
 #ifdef __USE_MISC
 /* Number of bits per word of `fd_set' (some code assumes this is 32).  */
-#define	NFDBITS			__NFDBITS
+# define NFDBITS		__NFDBITS
 #endif
 
 
@@ -75,6 +75,7 @@ extern int select __P ((int __nfds, __fd_set *__readfds,
 			__fd_set *__writefds, __fd_set *__exceptfds,
 			struct timeval *__timeout));
 
+#ifdef __USE_POSIX
 /* Same as above only that the TIMEOUT value is given with higher
    resolution.  This version should be used.  */
 extern int __pselect __P ((int __nfds, __fd_set *__readfds,
@@ -83,6 +84,7 @@ extern int __pselect __P ((int __nfds, __fd_set *__readfds,
 extern int pselect __P ((int __nfds, __fd_set *__readfds,
 			 __fd_set *__writefds, __fd_set *__exceptfds,
 			 struct timespec *__timeout));
+#endif
 
 __END_DECLS
 
diff --git a/nis/nis_call.c b/nis/nis_call.c
index fd777f5948..06f63ee52e 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -289,7 +289,7 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
     server_len = 1;
 
   if ((dbp = __bind_create (server, server_len, flags)) == NULL)
-    return NIS_UNAVAIL;
+    return NIS_NAMEUNREACHABLE;
   while (__bind_connect (dbp) != NIS_SUCCESS)
     {
       if (__bind_next (dbp) != NIS_SUCCESS)
@@ -351,6 +351,7 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
 		    break; /* No more servers to search in */
 		  goto again;
 		}
+	      break;
 	    case NIS_FINDDIRECTORY:
 	      if ((((fd_result *)resp)->status == NIS_NOTFOUND) ||
 		  (((fd_result *)resp)->status == NIS_NOSUCHNAME) ||
diff --git a/nis/nis_mkdir.c b/nis/nis_mkdir.c
index b762e93f27..ab693d7da1 100644
--- a/nis/nis_mkdir.c
+++ b/nis/nis_mkdir.c
@@ -24,23 +24,19 @@
 nis_error
 nis_mkdir (const_nis_name dir, const nis_server *server)
 {
-  nis_error res;
+  nis_error res, res2;
 
   if (server == NULL)
-    {
-      if (__do_niscall (dir, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
-			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			(caddr_t) &res, 0, NULL) != RPC_SUCCESS)
-	return NIS_RPCERROR;
-    }
-  else
-    {
-      if (__do_niscall2 (server, 1, NIS_MKDIR,
-			 (xdrproc_t) xdr_nis_name,
+    res2 = __do_niscall (dir, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
 			 (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			 (caddr_t) &res, 0, NULL) != RPC_SUCCESS)
-	return NIS_RPCERROR;
-    }
+			 (caddr_t) &res, 0, NULL);
+  else
+    res2 = __do_niscall2 (server, 1, NIS_MKDIR,
+			  (xdrproc_t) xdr_nis_name,
+			  (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
+			  (caddr_t) &res, 0, NULL);
+  if (res2 != NIS_SUCCESS)
+    return res2;
 
   return res;
 }
diff --git a/nis/nis_rmdir.c b/nis/nis_rmdir.c
index adf5924ada..ff84ed81e2 100644
--- a/nis/nis_rmdir.c
+++ b/nis/nis_rmdir.c
@@ -24,23 +24,17 @@
 nis_error
 nis_rmdir (const_nis_name dir, const nis_server *server)
 {
-  nis_error res;
+  nis_error res, res2;
 
   if (server == NULL)
-    {
-      if (__do_niscall (dir, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
+    return NIS_SYSTEMERROR;
+
+  res2 = __do_niscall2 (server, 1, NIS_RMDIR,
+			(xdrproc_t) xdr_nis_name,
 			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			(caddr_t) &res, 0, NULL) != RPC_SUCCESS)
-	return NIS_RPCERROR;
-    }
-  else
-    {
-      if (__do_niscall2 (server, 1, NIS_RMDIR,
-			 (xdrproc_t) xdr_nis_name,
-			 (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			 (caddr_t) &res, 0, NULL) != RPC_SUCCESS)
-	return NIS_RPCERROR;
-    }
+			(caddr_t) &res, 0, NULL);
+  if (res2 != NIS_SUCCESS)
+    return res2;
 
   return res;
 }
diff --git a/nis/rpcsvc/yp_prot.h b/nis/rpcsvc/yp_prot.h
index 42bc54c59d..82f93b49ed 100644
--- a/nis/rpcsvc/yp_prot.h
+++ b/nis/rpcsvc/yp_prot.h
@@ -12,6 +12,8 @@
 #include <rpc/rpc.h>
 #include <rpcsvc/ypclnt.h>
 
+__BEGIN_DECLS
+
 /*
  * The following procedures are supported by the protocol:
  *
@@ -72,12 +74,12 @@
 typedef struct {
   u_int keydat_len;
   char *keydat_val;
-} keydat;
+} keydat_t;
 
 typedef struct {
   u_int valdat_len;
   char *valdat_val;
-} valdat;
+} valdat_t;
 
 struct ypmap_parms {
   char *domain;			/* Null string means not available */
@@ -93,7 +95,7 @@ struct ypmap_parms {
 struct ypreq_key {
   const char *domain;
   const char *map;
-  keydat keydat;
+  keydat_t keydat;
 };
 
 struct ypreq_nokey {
@@ -149,7 +151,7 @@ typedef enum ypstat ypstat;
 
 struct ypresp_val {
   ypstat status;
-  valdat valdat;
+  valdat_t valdat;
 };
 
 struct ypresp_key_val {
@@ -160,11 +162,11 @@ struct ypresp_key_val {
      implementation somehow must change the order internally.  We
      don't want to follow this bad example since the user should be
      able to use rpcgen on this file.  */
-  keydat keydat;
-  valdat valdat;
+  keydat_t keydat;
+  valdat_t valdat;
 #else
-  valdat valdat;
-  keydat keydat;
+  valdat_t valdat;
+  keydat_t keydat;
 #endif
 };
 
@@ -340,8 +342,6 @@ struct ypresp_all {
   } ypresp_all_u;
 };
 
-__BEGIN_DECLS
-
 extern bool_t xdr_ypreq_key __P ((XDR *__xdrs, struct ypreq_key * __objp));
 extern bool_t xdr_ypreq_nokey __P ((XDR *__xdrs, struct ypreq_nokey * __objp));
 extern bool_t xdr_ypreq_xfr __P ((XDR *__xdrs, struct ypreq_xfr * __objp));
diff --git a/posix/Makefile b/posix/Makefile
index cbcb6d1b1b..a8adb1fe81 100644
--- a/posix/Makefile
+++ b/posix/Makefile
@@ -48,7 +48,8 @@ routines :=								      \
 	getopt getopt1 getopt_init					      \
 	sched_setp sched_getp sched_sets sched_gets sched_yield sched_primax  \
 	sched_primin sched_rr_gi					      \
-	getaddrinfo gai_strerror wordexp
+	getaddrinfo gai_strerror wordexp				      \
+	pread pwrite
 
 aux		:= init-posix environ
 tests		:= tstgetopt testfnm runtests
diff --git a/posix/sys/types.h b/posix/sys/types.h
index 45196103d4..675e2522fa 100644
--- a/posix/sys/types.h
+++ b/posix/sys/types.h
@@ -40,14 +40,30 @@ typedef __fsid_t fsid_t;
 #endif
 
 typedef __dev_t dev_t;
-typedef __gid_t gid_t;
 typedef __ino_t ino_t;
 typedef __mode_t mode_t;
 typedef __nlink_t nlink_t;
-typedef __off_t off_t;
 typedef __loff_t loff_t;
-typedef __pid_t pid_t;
+
+#ifndef gid_t
+typedef __gid_t gid_t;
+# define gid_t gid_t
+#endif
+
+#ifndef uid_t
 typedef __uid_t uid_t;
+# define uid_t uid_t
+#endif
+
+#ifndef off_t
+typedef __off_t off_t;
+# define off_t off_t
+#endif
+
+#ifndef pid_t
+typedef __pid_t pid_t;
+# define pid_t pid_t
+#endif
 
 #ifndef ssize_t
 typedef __ssize_t ssize_t;
diff --git a/posix/unistd.h b/posix/unistd.h
index f4a331bce3..9fcad90cb1 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -150,13 +150,36 @@ __BEGIN_DECLS
 
 #ifndef	ssize_t
 typedef __ssize_t ssize_t;
-#define	ssize_t	ssize_t
+# define ssize_t ssize_t
 #endif
 
 #define	__need_size_t
 #define __need_NULL
 #include <stddef.h>
 
+#ifdef __USE_UNIX98
+/* The Single Unix specification says that some more types are
+   available here.  */
+# ifndef gid_t
+typedef __gid_t gid_t;
+#  define gid_t gid_t
+# endif
+
+# ifndef uid_t
+typedef __uid_t uid_t;
+#  define uid_t uid_t
+# endif
+
+# ifndef off_t
+typedef __off_t off_t;
+#  define off_t off_t
+# endif
+
+# ifndef pid_t
+typedef __pid_t pid_t;
+#  define pid_t pid_t
+# endif
+#endif
 
 /* Values for the second argument to access.
    These may be OR'd together.  */
@@ -179,16 +202,16 @@ extern int euidaccess __P ((__const char *__name, int __type));
 
 /* Values for the WHENCE argument to lseek.  */
 #ifndef	_STDIO_H		/* <stdio.h> has the same definitions.  */
-#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.  */
+# 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.  */
 #endif
 
 #if defined __USE_BSD && !defined L_SET
 /* Old BSD names for the same constants; just for compatibility.  */
-#define	L_SET		SEEK_SET
-#define	L_INCR		SEEK_CUR
-#define	L_XTND		SEEK_END
+# define L_SET		SEEK_SET
+# define L_INCR		SEEK_CUR
+# define L_XTND		SEEK_END
 #endif
 
 
@@ -213,6 +236,19 @@ extern ssize_t read __P ((int __fd, __ptr_t __buf, size_t __nbytes));
 extern ssize_t __write __P ((int __fd, __const __ptr_t __buf, size_t __n));
 extern ssize_t write __P ((int __fd, __const __ptr_t __buf, size_t __n));
 
+#ifdef __USE_UNIX98
+/* Read NBYTES into BUF from FD at the given position OFFSET without
+   changing the file pointer.  Return the number read, -1 for errors
+   or 0 for EOF.  */
+extern ssize_t pread __P ((int __fd, __ptr_t __buf, size_t __nbytes,
+			   __off_t __offset));
+
+/* Write N bytes of BUF to FD at the given position OFFSET without
+   changing the file pointer.  Return the number written, or -1.  */
+extern ssize_t pwrite __P ((int __fd, __const __ptr_t __buf, size_t __n,
+			    __off_t __offset));
+#endif
+
 
 /* Create a one-way communication channel (pipe).
    If successful, two file descriptors are stored in PIPEDES;
@@ -427,7 +463,7 @@ extern __pid_t __bsd_getpgrp __P ((__pid_t __pid));
 #ifdef __FAVOR_BSD
 /* When we explicitely compile BSD sources use the BSD definition of this
    function.  Please note that we cannot use parameters for the macro.  */
-#define getpgrp __bsd_getpgrp
+# define getpgrp __bsd_getpgrp
 #endif
 
 /* Set the process group ID of the process matching PID to PGID.
@@ -777,8 +813,8 @@ extern int getdtablesize __P ((void));
 extern int __brk __P ((__ptr_t __addr));
 extern int brk __P ((__ptr_t __addr));
 
-#define __need_ptrdiff_t
-#include <stddef.h>
+# define __need_ptrdiff_t
+# include <stddef.h>
 
 /* Increase or decrease the end of accessible data space by DELTA bytes.
    If successful, returns the address the previous end of data space
@@ -814,10 +850,10 @@ extern long int syscall __P ((long int __sysno, ...));
    LEN is always relative to the current file position.
    The CMD argument is one of the following.  */
 
-#define F_ULOCK 0       /* Unlock a previously locked region.  */
-#define F_LOCK  1       /* Lock a region for exclusive use.  */
-#define F_TLOCK 2       /* Test and lock a region for exclusive use.  */
-#define F_TEST  3       /* Test a region for other processes locks.  */
+# define F_ULOCK 0	/* Unlock a previously locked region.  */
+# define F_LOCK  1	/* Lock a region for exclusive use.  */
+# define F_TLOCK 2	/* Test and lock a region for exclusive use.  */
+# define F_TEST  3	/* Test a region for other processes locks.  */
 
 extern int lockf __P ((int __fd, int __cmd, __off_t __len));
 #endif /* Use misc and F_LOCK not already defined.  */
@@ -828,7 +864,7 @@ extern int lockf __P ((int __fd, int __cmd, __off_t __len));
 /* Evaluate EXPRESSION, and repeat as long as it returns -1 with `errno'
    set to EINTR.  */
 
-#define TEMP_FAILURE_RETRY(expression) \
+# define TEMP_FAILURE_RETRY(expression) \
   (__extension__							      \
     ({ long int __result;						      \
        do __result = (long int) (expression);				      \
@@ -836,15 +872,16 @@ extern int lockf __P ((int __fd, int __cmd, __off_t __len));
        __result; }))							      \
 
 
-/* This variable is set nonzero at startup if the process's effective IDs
-   differ from its real IDs, or it is otherwise indicated that extra
-   security should be used.  When this is set the dynamic linker ignores
-   the various environment variables that normally affect it.  */
+/* This variable is set nonzero at startup if the process's effective
+   IDs differ from its real IDs, or it is otherwise indicated that
+   extra security should be used.  When this is set the dynamic linker
+   and some functions contained in the C library ignore various
+   environment variables that normally affect them.  */
 extern int __libc_enable_secure;
 
 #endif
 
-#ifdef __USE_POSIX199309
+#if defined __USE_POSIX199309 || defined __USE_UNIX98
 /* Synchronize at least the data part of a file with the underlying
    media.  */
 extern int fdatasync __P ((int __fildes));
@@ -869,7 +906,18 @@ extern void encrypt __P ((char *__block, int __edflag));
    FROM and copy the result to TO.  The value of TO must not be in the
    range [FROM - N + 1, FROM - 1].  If N is odd the first byte in FROM
    is without partner.  */
-extern void swab __P ((__const char *__from, char *__to, ssize_t __n));
+extern void swab __P ((__const __ptr_t __from, __ptr_t __to, ssize_t __n));
+#endif
+
+
+/* The Single Unix specification, version 2, demands these prototypes
+   to be here.  They are also found in <stdio.h>.  */
+#ifdef __USE_UNIX98
+/* Return the name of the controlling terminal.  */
+extern char *ctermid __P ((char *__s));
+
+/* Return the name of the current user.  */
+extern char *cuserid __P ((char *__s));
 #endif
 
 __END_DECLS
diff --git a/resolv/resolv.h b/resolv/resolv.h
index 4dae715659..06dba63182 100644
--- a/resolv/resolv.h
+++ b/resolv/resolv.h
@@ -61,14 +61,16 @@
 #ifndef _RESOLV_H
 #define	_RESOLV_H 1
 
+#include <features.h>
+
 #include <sys/param.h>
 #if (!defined(BSD)) || (BSD < 199306)
 # include <sys/bitypes.h>
 #else
 # include <sys/types.h>
 #endif
-#include <sys/cdefs.h>
 #include <stdio.h>
+#include <netinet/in.h>
 
 /*
  * Revision information.  This is the release date in YYYYMMDD format.
diff --git a/set-init.c b/set-init.c
index f4ecb2dfd9..4aea847db5 100644
--- a/set-init.c
+++ b/set-init.c
@@ -17,7 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <stdlib.h>
-#include "set-hooks.h"
+#include <set-hooks.h>
 
 DEFINE_HOOK_RUNNER (__libc_subinit, __libc_init,
 		    (int argc, char **argv, char **envp), (argc, argv, envp))
diff --git a/stdlib/fmtmsg.c b/stdlib/fmtmsg.c
index 101beb7f73..e7aab90046 100644
--- a/stdlib/fmtmsg.c
+++ b/stdlib/fmtmsg.c
@@ -332,6 +332,10 @@ addseverity (int severity, const char *string)
   int result;
   const char *new_string;
 
+  /* Prevent illegal SEVERITY values.  */
+  if (severity <= MM_INFO)
+    return MM_NOTOK;
+
   if (string == NULL)
     /* We want to remove the severity class.  */
     new_string = NULL;
@@ -339,7 +343,7 @@ addseverity (int severity, const char *string)
     {
       new_string = __strdup (string);
 
-      if (new_string == NULL || severity <= MM_INFO)
+      if (new_string == NULL)
 	/* Allocation failed or illegal value.  */
 	return MM_NOTOK;
     }
@@ -359,3 +363,23 @@ addseverity (int severity, const char *string)
 
   return result;
 }
+
+
+static void __attribute__ ((unused))
+free_mem (void)
+{
+  struct severity_info *runp = severity_list;
+
+  while (runp != NULL)
+    if (runp->severity > MM_INFO)
+      {
+	/* This is data we have to release.  */
+	struct severity_info *here = runp;
+	free ((char *) runp->string);
+	runp = runp->next;
+	free (here);
+      }
+    else
+      runp = runp->next;
+}
+text_set_element (__libc_subfreeres, free_mem);
diff --git a/stdlib/tst-strtol.c b/stdlib/tst-strtol.c
index 62acafbfe3..483e713739 100644
--- a/stdlib/tst-strtol.c
+++ b/stdlib/tst-strtol.c
@@ -5,7 +5,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <strings.h>
+#include <string.h>
 #include <limits.h>
 
 struct ltest
diff --git a/string/bits/string2.h b/string/bits/string2.h
index 8555d677ab..e0a8e75311 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -369,18 +369,40 @@ __STRING2_COPY_TYPE (8);
 #ifndef _HAVE_STRING_ARCH_strcmp
 # define strcmp(s1, s2) \
   (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2)      \
-		  && (sizeof (s1)[0] != 1 || strlen (s1) >= 4)		      \
-		  && (sizeof (s2)[0] != 1 || strlen (s2) >= 4)		      \
+		  && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4)	      \
+		  && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4)	      \
 		  ? memcmp (s1, s2, (strlen (s1) < strlen (s2)		      \
 				     ? strlen (s1) : strlen (s2)) + 1)	      \
-		  : (__builtin_constant_p (s1) && sizeof (s1)[0] == 1	      \
-		     && sizeof (s2)[0] == 1 && strlen (s1) < 4		      \
-		     ? __strcmp_cg (s1, s2, strlen (s1))		      \
-		     : (__builtin_constant_p (s2) && sizeof (s1)[0] == 1      \
-			&& sizeof (s2)[0] == 1 && strlen (s2) < 4	      \
-			? __strcmp_gc (s1, s2, strlen (s2))		      \
+		  : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1	      \
+		     && sizeof ((s2)[0]) == 1 && strlen (s1) < 4	      \
+		     ? (__builtin_constant_p (s2)			      \
+			? __strcmp_cc (s1, s2, strlen (s1))		      \
+			: __strcmp_cg (s1, s2, strlen (s1)))		      \
+		     : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1    \
+			&& sizeof ((s2)[0]) == 1 && strlen (s2) < 4	      \
+			? (__builtin_constant_p (s1)			      \
+			   ? __strcmp_cc (s1, s2, strlen (s2))		      \
+			   : __strcmp_gc (s1, s2, strlen (s2)))		      \
 			: strcmp (s1, s2)))))
 
+# define __strcmp_cc(s1, s2, l) \
+  (__extension__ ({ register int __result = ((unsigned char) (s1)[0]	      \
+					     - (unsigned char) (s2)[0]);      \
+		    if (l > 0 && __result == 0)				      \
+		      {							      \
+			__result = ((unsigned char) (s1)[1]		      \
+				    - (unsigned char) (s2)[1]);		      \
+			if (l > 1 && __result == 0)			      \
+			  {						      \
+			    __result = ((unsigned char) (s1)[2]		      \
+					- (unsigned char) (s2)[2]);	      \
+			    if (l > 2 && __result == 0)			      \
+			      __result = ((unsigned char) (s1)[3]	      \
+					  - (unsigned char) (s2)[3]);	      \
+			  }						      \
+		      }							      \
+		    __result; }))
+
 # define __strcmp_cg(s1, s2, l1) \
   (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2);     \
 		    register int __result = (unsigned char) (s1)[0] - __s2[0];\
diff --git a/string/strings.h b/string/strings.h
index 701132992a..20a1af1d84 100644
--- a/string/strings.h
+++ b/string/strings.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -16,17 +16,41 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-/* Compatibility with BSD string(3).  */
-
 #ifndef	_STRINGS_H
 #define	_STRINGS_H	1
 
 #include <features.h>
+#define __need_size_t
+#include <stddef.h>
+
+__BEGIN_DECLS
+
+/* Compare N bytes of S1 and S2 (same as memcmp).  */
+extern int bcmp __P ((__const __ptr_t __s1, __const __ptr_t __s2, size_t __n));
+
+/* Copy N bytes of SRC to DEST (like memmove, but args reversed).  */
+extern void bcopy __P ((__const __ptr_t __src, __ptr_t __dest, size_t __n));
+
+/* Set N bytes of S to 0.  */
+extern void bzero __P ((__ptr_t __s, size_t __n));
+
+/* Return the position of the first bit set in I, or 0 if none are set.
+   The least-significant bit is position 1, the most-significant 32.  */
+extern int ffs __P ((int __i));
+
+/* Find the first occurrence of C in S (same as strchr).  */
+extern char *index __P ((__const char *__s, int __c));
+
+/* Find the last occurrence of C in S (same as strrchr).  */
+extern char *rindex __P ((__const char *__s, int __c));
 
+/* Compare S1 and S2, ignoring case.  */
+extern int strcasecmp __P ((__const char *__s1, __const char *__s2));
 
-#ifndef	_STRING_H
-#include <string.h>
-#endif	/* string.h  */
+/* Compare no more than N chars of S1 and S2, ignoring case.  */
+extern int strncasecmp __P ((__const char *__s1, __const char *__s2,
+			     size_t __n));
 
+__END_DECLS
 
 #endif	/* strings.h  */
diff --git a/string/swab.c b/string/swab.c
index c9cf7004ea..325ead5a93 100644
--- a/string/swab.c
+++ b/string/swab.c
@@ -19,8 +19,11 @@
 #include <unistd.h>
 
 void
-swab (const char *from, char *to, ssize_t n)
+swab (const void *bfrom, void *bto, ssize_t n)
 {
+  const char *from = (const char *) bfrom;
+  char *to = (char *) bto;
+
   n &= ~((ssize_t) 1);
   while (n > 1)
     {
diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c
index 30a051724f..f528c3018b 100644
--- a/sunrpc/clnt_simp.c
+++ b/sunrpc/clnt_simp.c
@@ -45,7 +45,7 @@ static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
 #include <rpc/rpc.h>
 #include <sys/socket.h>
 #include <netdb.h>
-#include <strings.h>
+#include <string.h>
 
 static struct callrpc_private
   {
diff --git a/sunrpc/rpc/auth_des.h b/sunrpc/rpc/auth_des.h
index 87fb8f0e99..0177ede5e9 100644
--- a/sunrpc/rpc/auth_des.h
+++ b/sunrpc/rpc/auth_des.h
@@ -17,9 +17,10 @@
    Boston, MA 02111-1307, USA.  */
 
 #ifndef _RPC_AUTH_DES_H
-
 #define _RPC_AUTH_DES_H	1
+
 #include <sys/cdefs.h>
+#include <rpc/auth.h>
 
 __BEGIN_DECLS
 
@@ -34,9 +35,9 @@ enum authdes_namekind
    a conversation key and the window */
 struct authdes_fullname
   {
-    char *name;			/* network name of client, up to MAXNETNAMELEN */
-    des_block key;		/* conversation key */
-    u_long window;		/* associated window */
+    char *name;		/* network name of client, up to MAXNETNAMELEN */
+    des_block key;	/* conversation key */
+    u_long window;	/* associated window */
   };
 
 /* A credential */
@@ -53,7 +54,7 @@ struct authdes_verf
     union
       {
 	struct timeval adv_ctime;	/* clear time */
-	des_block adv_xtime;	/* crypt time */
+	des_block adv_xtime;		/* crypt time */
       }
     adv_time_u;
     u_long adv_int_u;
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index 28ca38315e..ef808d2e7d 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -368,7 +368,7 @@ __strlen_g (__const char *__str)
 #define _HAVE_STRING_ARCH_strcpy 1
 #define strcpy(dest, src) \
   (__extension__ (__builtin_constant_p (src)				      \
-		  ? (sizeof (src[0]) == 1 && strlen (src) + 1 <= 8	      \
+		  ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8	      \
 		     ? __strcpy_small (dest, src, strlen (src) + 1)	      \
 		     : (char *) memcpy (dest, src, strlen (src) + 1))	      \
 		  : __strcpy_g (dest, src)))
@@ -800,18 +800,40 @@ __strncat_g (char *__dest, __const char __src[], size_t __n)
 #define _HAVE_STRING_ARCH_strcmp 1
 #define strcmp(s1, s2) \
   (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2)      \
-		  && (sizeof (s1)[0] != 1 || strlen (s1) >= 4)		      \
-		  && (sizeof (s2)[0] != 1 || strlen (s2) >= 4)		      \
+		  && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4)	      \
+		  && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4)	      \
 		  ? memcmp (s1, s2, (strlen (s1) < strlen (s2)		      \
 				     ? strlen (s1) : strlen (s2)) + 1)	      \
-		  : (__builtin_constant_p (s1) && sizeof (s1)[0] == 1	      \
-		     && sizeof (s2)[0] == 1 && strlen (s1) < 4		      \
-		     ? __strcmp_cg (s1, s2, strlen (s1))		      \
-		     : (__builtin_constant_p (s2) && sizeof (s1)[0] == 1      \
-			&& sizeof (s2)[0] == 1 && strlen (s2) < 4	      \
-			? __strcmp_gc (s1, s2, strlen (s2))		      \
+		  : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1	      \
+		     && sizeof ((s2)[0]) == 1 && strlen (s1) < 4	      \
+		     ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1    \
+			? __strcmp_cc (s1, s2, strlen (s1))		      \
+			: __strcmp_cg (s1, s2, strlen (s1)))		      \
+		     : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1    \
+			&& sizeof ((s2)[0]) == 1 && strlen (s2) < 4	      \
+			? (__builtin_constant_p (s1)			      \
+			   ? __strcmp_cc (s1, s2, strlen (s2))		      \
+			   : __strcmp_gc (s1, s2, strlen (s2)))		      \
 			: __strcmp_gg (s1, s2)))))
 
+#define __strcmp_cc(s1, s2, l) \
+  (__extension__ ({ register int __result = ((unsigned char) (s1)[0]	      \
+					     - (unsigned char) (s2)[0]);      \
+		    if (l > 0 && __result == 0)				      \
+		      {							      \
+			__result = ((unsigned char) (s1)[1]		      \
+				    - (unsigned char) (s2)[1]);		      \
+			if (l > 1 && __result == 0)			      \
+			  {						      \
+			    __result = ((unsigned char) (s1)[2]		      \
+					- (unsigned char) (s2)[2]);	      \
+			    if (l > 2 && __result == 0)			      \
+			      __result = ((unsigned char) (s1)[3]	      \
+					  - (unsigned char) (s2)[3]);	      \
+			  }						      \
+		      }							      \
+		    __result; }))
+
 #define __strcmp_cg(s1, s2, l1) \
   (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2);     \
 		    register int __result = (unsigned char) (s1)[0] - __s2[0];\
@@ -1076,32 +1098,28 @@ __strcspn_c1 (__const char *__s, int __reject)
   return (__res - 1) - __s;
 }
 
-#ifdef __PIC__
 __STRING_INLINE size_t
 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
 {
   register __const char *__res;
-  int __mem;
   __asm__ __volatile__
-    ("movl	%%ebx,%1\n\t"
-     "movl	%%ecx,%%ebx\n\t"
-     "cld\n"
+    ("cld\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%2,%%edi\n\t"
+     "movl	%3,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n"
-     "2:\n\t"
-     "movl	%1,%%ebx"
-     : "=S" (__res), "=&m" (__mem)
-     : "c" (__reject_len), "0" (__s), "r" (__reject), "1" (__mem)
+     "2:"
+     : "=S" (__res)
+     : "0" (__s), "d" (__reject), "g" (__reject_len)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
 
+#ifdef __PIC__
 __STRING_INLINE size_t
 __strcspn_g (__const char *__s, __const char *__reject)
 {
@@ -1131,27 +1149,6 @@ __strcspn_g (__const char *__s, __const char *__reject)
 }
 #else
 __STRING_INLINE size_t
-__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
-{
-  register __const char *__res;
-  __asm__ __volatile__
-    ("cld\n"
-     "1:\n\t"
-     "lodsb\n\t"
-     "testb	%%al,%%al\n\t"
-     "je	2f\n\t"
-     "movl	%%ebx,%%edi\n\t"
-     "movl	%%edx,%%ecx\n\t"
-     "repne; scasb\n\t"
-     "jne	1b\n"
-     "2:"
-     : "=S" (__res)
-     : "d" (__reject_len), "0" (__s), "b" (__reject)
-     : "ax", "cx", "di", "cc");
-  return (__res - 1) - __s;
-}
-
-__STRING_INLINE size_t
 __strcspn_g (__const char *__s, __const char *__reject)
 {
   register __const char *__res;
@@ -1199,40 +1196,35 @@ __strspn_c1 (__const char *__s, int __accept)
      "movb	(%0),%%al\n\t"
      "leal	1(%0),%0\n\t"
      "cmpb	%%ah,%%al\n\t"
-     "je	1b\n"
-     "2:"
+     "je	1b"
      : "=r" (__res)
      : "a" (__accept), "0" (__s)
      : "ax", "cc");
   return (__res - 1) - __s;
 }
 
-#ifdef __PIC__
 __STRING_INLINE size_t
 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
   register __const char *__res;
-  int __mem;
   __asm__ __volatile__
-    ("movl	%%ebx,%1\n\t"
-     "movl	%%ecx,%%ebx\n\t"
-     "cld\n"
+    ("cld\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%%edx,%%edi\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%2,%%edi\n\t"
+     "movl	%3,%%ecx\n\t"
      "repne; scasb\n\t"
      "je	1b\n"
-     "2:\n\t"
-     "movl	%1,%%ebx"
-     : "=S" (__res), "=m" (__mem)
-     : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+     "2:"
+     : "=S" (__res)
+     : "0" (__s), "d" (__accept), "g" (__accept_len)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
 
+#ifdef __PIC__
 __STRING_INLINE size_t
 __strspn_g (__const char *__s, __const char *__accept)
 {
@@ -1262,27 +1254,6 @@ __strspn_g (__const char *__s, __const char *__accept)
 }
 #else
 __STRING_INLINE size_t
-__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
-{
-  register __const char *__res;
-  __asm__ __volatile__
-    ("cld\n"
-     "1:\n\t"
-     "lodsb\n\t"
-     "testb	%%al,%%al\n\t"
-     "je	2f\n\t"
-     "movl	%%ebx,%%edi\n\t"
-     "movl	%%edx,%%ecx\n\t"
-     "repne; scasb\n\t"
-     "je	1b\n"
-     "2:"
-     : "=S" (__res)
-     : "d" (__accept_len), "0" (__s), "b" (__accept), "D" (__accept)
-     : "ax", "cx", "dx", "di", "cc");
-  return (__res - 1) - __s;
-}
-
-__STRING_INLINE size_t
 __strspn_g (__const char *__s, __const char *__accept)
 {
   register __const char *__res;
@@ -1319,36 +1290,32 @@ __strspn_g (__const char *__s, __const char *__accept)
 			: __strpbrk_cg (s, accept, strlen (accept))))	      \
 		  : __strpbrk_g (s, accept)))
 
-#ifdef __PIC__
 __STRING_INLINE char *
 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
   register char *__res;
-  int __mem;
   __asm__ __volatile__
-    ("movl	%%ebx,%1\n\t"
-     "movl	%%ecx,%%ebx\n\t"
-     "cld\n"
+    ("cld\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%%edx,%%edi\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%2,%%edi\n\t"
+     "movl	%3,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n\t"
      "decl	%0\n\t"
      "jmp	3f\n"
      "2:\n\t"
      "xorl	%0,%0\n"
-     "3:\n\t"
-     "movl	%1,%%ebx"
-     : "=S" (__res), "=m" (__mem)
-     : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+     "3:"
+     : "=S" (__res)
+     : "0" (__s), "d" (__accept), "g" (__accept_len)
      : "ax", "cx", "di", "cc");
   return __res;
 }
 
+#ifdef __PIC__
 __STRING_INLINE char *
 __strpbrk_g (__const char *__s, __const char *__accept)
 {
@@ -1382,32 +1349,6 @@ __strpbrk_g (__const char *__s, __const char *__accept)
 }
 #else
 __STRING_INLINE char *
-__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
-{
-  register char *__res;
-  __asm__ __volatile__
-    ("movl	%%ebx,%%edi\n\t"
-     "cld\n"
-     "1:\n\t"
-     "lodsb\n\t"
-     "testb	%%al,%%al\n\t"
-     "je	2f\n\t"
-     "movl	%%ebx,%%edi\n\t"
-     "movl	%%edx,%%ecx\n\t"
-     "repne; scasb\n\t"
-     "jne	1b\n\t"
-     "decl	%0\n\t"
-     "jmp	3f\n"
-     "2:\n\t"
-     "xorl	%0,%0\n"
-     "3:"
-     : "=S" (__res)
-     : "d" (__accept_len), "0" (__s), "b" (__accept)
-     : "ax", "cx", "dx", "di", "cc");
-  return __res;
-}
-
-__STRING_INLINE char *
 __strpbrk_g (__const char *__s, __const char *__accept)
 {
   register char *__res;
@@ -1440,18 +1381,15 @@ __strpbrk_g (__const char *__s, __const char *__accept)
 
 /* Find the first occurrence of NEEDLE in HAYSTACK.  */
 #define _HAVE_STRING_ARCH_strstr 1
-#ifdef __PIC__
-/* XXX GCC has problems to spill the registers.  */
-# define strstr(haystack, needle) \
+#define strstr(haystack, needle) \
   (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
 		  ? ((needle)[0] == '\0'				      \
 		     ? haystack						      \
 		     : ((needle)[1] == '\0'				      \
-			? strchr (haystack, (needle)[0])		     \
-			: strstr (haystack, needle)))			      \
-		  : strstr (haystack, needle)))
+			? strchr (haystack, (needle)[0])		      \
+			: __strstr_cg (haystack, needle, strlen (needle))))   \
+		  : __strstr_g (haystack, needle)))
 
-# if 0
 /* Please note that this function need not handle NEEDLEs with a
    length shorter than two.  */
 __STRING_INLINE char *
@@ -1459,29 +1397,30 @@ __strstr_cg (__const char *__haystack, __const char __needle[],
 	     size_t __needle_len)
 {
   register char *__res;
-  int __mem;
   __asm__ __volatile__
-    ("movl	%%ebx,%1\n\t"
-     "movl	%%ecx,%%ebx\n"
-     "cld\n" \
+    ("cld\n" \
      "1:\n\t"
-     "movl	%%edx,%%edi\n\t"
-     "movl	%%esi,%%eax\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%3,%%edi\n\t"
+     "movl	%2,%%eax\n\t"
+     "movl	%1,%%ecx\n\t"
      "repe; cmpsb\n\t"
      "je	2f\n\t"
      "cmpb	$0,-1(%%esi)\n\t"
-     "leal	1(%%eax),%%esi\n\t"
+     "leal	1(%%eax),%2\n\t"
      "jne	1b\n\t"
      "xorl	%%eax,%%eax\n"
-     "2:\n\t"
-     "movl	%1,%%ebx"
-     : "=a" (__res), "=m" (__mem)
-     : "c" (__needle_len), "S" (__haystack), "d" (__needle), "1" (__mem)
+     "2:"
+     : "=a" (__res)
+     : "g" (__needle_len), "S" (__haystack), "d" (__needle)
      : "cx", "di", "si", "cc");
   return __res;
 }
 
+#ifdef __PIC__
+# if 1
+/* For now this does not always works due to spilling problems.  */
+#  define __strstr_g(haystack, needle) strstr (haystack, needle)
+# else
 __STRING_INLINE char *
 __strstr_g (__const char *__haystack, __const char *__needle)
 {
@@ -1514,39 +1453,6 @@ __strstr_g (__const char *__haystack, __const char *__needle)
 }
 # endif
 #else
-# define strstr(haystack, needle) \
-  (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
-		  ? ((needle)[0] == '\0'				      \
-		     ? haystack						      \
-		     : ((needle)[1] == '\0'				      \
-			? strchr (haystack, (needle)[0]) 		      \
-			: __strstr_cg (haystack, needle, strlen (needle))))   \
-		  : __strstr_g (haystack, needle)))
-
-__STRING_INLINE char *
-__strstr_cg (__const char *__haystack, __const char __needle[],
-	     size_t __needle_len)
-{
-  register char *__res;
-  __asm__ __volatile__
-    ("cld\n" \
-     "1:\n\t"
-     "movl	%%ebx,%%edi\n\t"
-     "movl	%%esi,%%eax\n\t"
-     "movl	%%edx,%%ecx\n\t"
-     "repe; cmpsb\n\t"
-     "je	2f\n\t"
-     "cmpb	$0,-1(%%esi)\n\t"
-     "leal	1(%%eax),%%esi\n\t"
-     "jne	1b\n\t"
-     "xorl	%%eax,%%eax\n"
-     "2:"
-     : "=a" (__res)
-     : "d" (__needle_len), "S" (__haystack), "b" (__needle)
-     : "cx", "dx", "di", "si", "cc");
-  return __res;
-}
-
 __STRING_INLINE char *
 __strstr_g (__const char *__haystack, __const char *__needle)
 {
diff --git a/sysdeps/m68k/fpu/bits/mathinline.h b/sysdeps/m68k/fpu/bits/mathinline.h
index 2ab570fba5..1e68ea00c0 100644
--- a/sysdeps/m68k/fpu/bits/mathinline.h
+++ b/sysdeps/m68k/fpu/bits/mathinline.h
@@ -120,6 +120,7 @@ __inline_mathop(__ieee754_asin, asin)
 __inline_mathop(__ieee754_cosh, cosh)
 __inline_mathop(__ieee754_sinh, sinh)
 __inline_mathop(__ieee754_exp, etox)
+__inline_mathop(__ieee754_exp2, twotox)
 __inline_mathop(__ieee754_log10, log10)
 __inline_mathop(__ieee754_log, logn)
 __inline_mathop(__ieee754_sqrt, sqrt)
@@ -139,7 +140,6 @@ __inline_mathop(__log1p, lognp1)
 __inline_mathop(__significand, getman)
 
 __inline_mathop(__log2, log2)
-__inline_mathop(__exp2, twotox)
 __inline_mathop(__trunc, intrz)
 
 #if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
diff --git a/sysdeps/m68k/fpu/s_exp2.c b/sysdeps/m68k/fpu/s_exp2.c
index 389528092a..24fac4fce6 100644
--- a/sysdeps/m68k/fpu/s_exp2.c
+++ b/sysdeps/m68k/fpu/s_exp2.c
@@ -1,2 +1,2 @@
-#define FUNC exp2
-#include <s_atan.c>
+#define FUNC __ieee754_exp2
+#include <e_acos.c>
diff --git a/sysdeps/m68k/fpu/s_exp2f.c b/sysdeps/m68k/fpu/s_exp2f.c
index 20ac916d1a..593842e4e5 100644
--- a/sysdeps/m68k/fpu/s_exp2f.c
+++ b/sysdeps/m68k/fpu/s_exp2f.c
@@ -1,2 +1,2 @@
-#define FUNC exp2f
-#include <s_atanf.c>
+#define FUNC __ieee754_exp2f
+#include <e_acosf.c>
diff --git a/sysdeps/m68k/fpu/s_exp2l.c b/sysdeps/m68k/fpu/s_exp2l.c
index 19121b929d..0ab2a428c0 100644
--- a/sysdeps/m68k/fpu/s_exp2l.c
+++ b/sysdeps/m68k/fpu/s_exp2l.c
@@ -1,2 +1,2 @@
-#define FUNC exp2l
-#include <s_atanl.c>
+#define FUNC __ieee754_exp2l
+#include <e_acosl.c>
diff --git a/sysdeps/mach/hurd/cthreads.c b/sysdeps/mach/hurd/cthreads.c
index c63ae73bb5..9d92e9e950 100644
--- a/sysdeps/mach/hurd/cthreads.c
+++ b/sysdeps/mach/hurd/cthreads.c
@@ -1,3 +1,21 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
 #include <bits/libc-lock.h>
 #include <errno.h>
 #include <stdlib.h>
diff --git a/sysdeps/posix/pread.c b/sysdeps/posix/pread.c
new file mode 100644
index 0000000000..300aabac65
--- /dev/null
+++ b/sysdeps/posix/pread.c
@@ -0,0 +1,56 @@
+/* Read block from given position in file without changing file pointer.
+   POSIX version.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <unistd.h>
+
+ssize_t
+pread (int fd, void *buf, size_t nbyte, off_t offset)
+{
+  /* Since we must not change the file pointer preserve the value so that
+     we can restore it later.  */
+  int save_errno;
+  ssize_t result;
+  off_t old_offset = lseek (fd, 0, SEEK_CUR);
+  if (old_offset == (off_t) -1)
+    return -1;
+
+  /* Set to wanted position.  */
+  if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
+    return -1;
+
+  /* Write out the data.  */
+  result = read (fd, buf, nbyte);
+
+  /* Now we have to restore the position.  If this fails we have to
+     return this as an error.  But if the writing also failed we
+     return this error.  */
+  save_errno = errno;
+  if (lseek (fd, old_offset, SEEK_SET) == (off_t) -1)
+    {
+      if (result == -1)
+	__set_errno (save_errno);
+      return -1;
+    }
+  __set_errno (save_errno);
+
+  return result;
+}
diff --git a/sysdeps/posix/pwrite.c b/sysdeps/posix/pwrite.c
new file mode 100644
index 0000000000..7c1ed45cca
--- /dev/null
+++ b/sysdeps/posix/pwrite.c
@@ -0,0 +1,56 @@
+/* Write block to given position in file without changing file pointer.
+   POSIX version.
+   Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <unistd.h>
+
+ssize_t
+pwrite (int fd, const void *buf, size_t nbyte, off_t offset)
+{
+  /* Since we must not change the file pointer preserve the value so that
+     we can restore it later.  */
+  int save_errno;
+  ssize_t result;
+  off_t old_offset = lseek (fd, 0, SEEK_CUR);
+  if (old_offset == (off_t) -1)
+    return -1;
+
+  /* Set to wanted position.  */
+  if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
+    return -1;
+
+  /* Write out the data.  */
+  result = write (fd, buf, nbyte);
+
+  /* Now we have to restore the position.  If this fails we have to
+     return this as an error.  But if the writing also failed we
+     return this error.  */
+  save_errno = errno;
+  if (lseek (fd, old_offset, SEEK_SET) == (off_t) -1)
+    {
+      if (result == -1)
+	__set_errno (save_errno);
+      return -1;
+    }
+  __set_errno (save_errno);
+
+  return result;
+}
diff --git a/sysdeps/stub/pread.c b/sysdeps/stub/pread.c
new file mode 100644
index 0000000000..8d937c76c5
--- /dev/null
+++ b/sysdeps/stub/pread.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Read NBYTES into BUF from FD at the given position OFFSET without
+   changing the file pointer.  Return the number read or -1.  */
+ssize_t
+pread (int fd, void *buf, size_t nbytes, off_t offset)
+{
+  if (nbytes == 0)
+    return 0;
+  if (fd < 0)
+    {
+      __set_errno (EBADF);
+      return -1;
+    }
+  if (buf == NULL || offset < 0)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (pread)
diff --git a/sysdeps/stub/pwrite.c b/sysdeps/stub/pwrite.c
new file mode 100644
index 0000000000..ee670d9670
--- /dev/null
+++ b/sysdeps/stub/pwrite.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Write NBYTES of BUF to FD at given position OFFSET without changing
+   the file position.  Return the number written, or -1.  */
+ssize_t
+pwrite (int fd, const void *buf, size_t nbytes, off_t offset)
+{
+  if (nbytes == 0)
+    return 0;
+  if (fd < 0)
+    {
+      __set_errno (EBADF);
+      return -1;
+    }
+  if (buf == NULL || offset < 0)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  __set_errno (ENOSYS);
+  return -1;
+}
+stub_warning (pwrite)
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 0545f4426a..4bfc3eb352 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -15,7 +15,8 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h sys/mtio.h \
 		  sys/module.h sys/io.h sys/klog.h sys/kdaemon.h \
 		  sys/user.h sys/sysmacros.h sys/procfs.h \
 		  sys/debugreg.h sys/kd.h sys/soundcard.h sys/vt.h \
-		  sys/quota.h sys/fsuid.h bits/mman.h
+		  sys/quota.h sys/fsuid.h bits/mman.h \
+		  scsi/sg.h
 
 install-others += $(inst_includedir)/bits/syscall.h
 
diff --git a/sysdeps/unix/sysv/linux/scsi/sg.h b/sysdeps/unix/sysv/linux/scsi/sg.h
new file mode 100644
index 0000000000..c0a0c3a6d5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/scsi/sg.h
@@ -0,0 +1,59 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   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., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/*
+   History:
+    Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user
+     process control of SCSI devices.
+    Development Sponsored by Killy Corp. NY NY
+*/
+
+#ifndef _SCSI_SG_H
+#define _SCSI_SG_H	1
+
+/* An SG device is accessed by writing "packets" to it, the replies
+   are then read using the read call.  The same header is used for
+   replies; ignore the reply_len field.  */
+
+struct sg_header
+ {
+   int pack_len;			/* length of incoming packet
+					   (including header).  */
+   int reply_len;			/* max length of expected reply.  */
+   int pack_id;				/* id number of packet.  */
+   int result;				/* 0==ok, otherwise error number.  */
+   unsigned int twelve_byte:1;		/* force 12 byte command length for
+					   group 6 & 7 commands.  */
+   unsigned int other_flags:31;		/* for future use.  */
+   unsigned char sense_buffer[16];	/* used only by reads. */
+   /* command follows then data for command.  */
+ };
+
+/* ioctl's */
+#define SG_SET_TIMEOUT 0x2201  /* set timeout *(int *)arg==timeout */
+#define SG_GET_TIMEOUT 0x2202  /* get timeout return timeout */
+
+#define SG_DEFAULT_TIMEOUT (60*HZ) /* 1 minute timeout */
+#define SG_DEFAULT_RETRIES 1
+
+#define SG_MAX_QUEUE 4 /* maximum outstanding request, arbitrary, may be
+			  changed if sufficient DMA buffer room available.  */
+
+#define SG_BIG_BUFF 32768
+
+#endif	/* scsi/sg.h */
diff --git a/sysdeps/unix/sysv/linux/sys/mman.h b/sysdeps/unix/sysv/linux/sys/mman.h
index 0f56a70c32..c8f512c00c 100644
--- a/sysdeps/unix/sysv/linux/sys/mman.h
+++ b/sysdeps/unix/sysv/linux/sys/mman.h
@@ -23,6 +23,8 @@
 #include <features.h>
 
 #include <bits/types.h>
+#define __need_size_t
+#include <stddef.h>
 
 /* Get the bit values from the kernel header file.  */
 #include <bits/mman.h>
diff --git a/sysdeps/unix/sysv/linux/syscalls.list b/sysdeps/unix/sysv/linux/syscalls.list
index d5c486d7d0..6028a04aaf 100644
--- a/sysdeps/unix/sysv/linux/syscalls.list
+++ b/sysdeps/unix/sysv/linux/syscalls.list
@@ -32,7 +32,7 @@ nfsservctl	EXTRA	nfsservctl	3	nfsservctl
 pause		-	pause		0	__libc_pause	pause
 personality	init-first personality	1	__personality	personality
 pipe		-	pipe		1	__pipe		pipe
-prctl		EXTRA	prctl		5
+prctl		EXTRA	prctl		5	prctl
 query_module	EXTRA	query_module	5	query_module
 quotactl	EXTRA	quotactl	4	quotactl
 s_getdents	EXTRA	getdents	3	__getdents
diff --git a/time/strftime.c b/time/strftime.c
index 4ecbc5a519..1da36e12d6 100644
--- a/time/strftime.c
+++ b/time/strftime.c
@@ -34,6 +34,10 @@
 # include "../locale/localeinfo.h"
 #endif
 
+#if defined emacs && !defined HAVE_BCOPY
+# define HAVE_MEMCPY 1
+#endif
+
 #include <ctype.h>
 #include <sys/types.h>		/* Some systems define `time_t' here.  */
 
@@ -138,6 +142,7 @@ extern char *tzname[];
 # if ! HAVE_LOCALTIME_R
 #  if ! HAVE_TM_GMTOFF
 /* Approximate gmtime_r as best we can in its absence.  */
+#   undef gmtime_r
 #   define gmtime_r my_gmtime_r
 static struct tm *gmtime_r __P ((const time_t *, struct tm *));
 static struct tm *
@@ -154,6 +159,7 @@ gmtime_r (t, tp)
 #  endif /* ! HAVE_TM_GMTOFF */
 
 /* Approximate localtime_r as best we can in its absence.  */
+#  undef localtime_r
 #  define localtime_r my_ftime_localtime_r
 static struct tm *localtime_r __P ((const time_t *, struct tm *));
 static struct tm *
@@ -327,7 +333,7 @@ tm_diff (a, b)
 #define YDAY_MINIMUM (-366)
 static int iso_week_days __P ((int, int));
 #ifdef __GNUC__
-inline
+__inline__
 #endif
 static int
 iso_week_days (yday, wday)
diff --git a/time/time.h b/time/time.h
index d062ba1cc0..184f4eda10 100644
--- a/time/time.h
+++ b/time/time.h
@@ -22,10 +22,10 @@
 
 #ifndef	_TIME_H
 
-#if	(! defined __need_time_t && !defined __need_clock_t && \
-	 ! defined __need_timespec)
-#define	_TIME_H		1
-#include <features.h>
+#if (! defined __need_time_t && !defined __need_clock_t && \
+     ! defined __need_timespec)
+# define _TIME_H	1
+# include <features.h>
 
 __BEGIN_DECLS
 
@@ -33,9 +33,9 @@ __BEGIN_DECLS
 
 #ifdef	_TIME_H
 /* Get size_t and NULL from <stddef.h>.  */
-#define	__need_size_t
-#define	__need_NULL
-#include <stddef.h>
+# define __need_size_t
+# define __need_NULL
+# include <stddef.h>
 #endif /* <time.h> included.  */
 
 
@@ -44,22 +44,22 @@ __BEGIN_DECLS
 
 /* This defines CLOCKS_PER_SEC, which is the number of processor clock
    ticks per second.  */
-#include <bits/time.h>
+# include <bits/time.h>
 
 /* This is the obsolete POSIX.1-1988 name for the same constant.  */
-#ifdef	__USE_POSIX
-#ifndef CLK_TCK
-#define	CLK_TCK		CLOCKS_PER_SEC
-#endif
-#endif
+# ifdef	__USE_POSIX
+#  ifndef CLK_TCK
+#   define CLK_TCK	CLOCKS_PER_SEC
+#  endif
+# endif
 
 #endif /* <time.h> included.  */
 
 
 #if !defined __clock_t_defined && (defined _TIME_H || defined __need_clock_t)
-#define	__clock_t_defined	1
+# define __clock_t_defined	1
 
-#include <bits/types.h>
+# include <bits/types.h>
 
 /* Returned by `clock'.  */
 typedef __clock_t clock_t;
@@ -68,9 +68,9 @@ typedef __clock_t clock_t;
 #undef	__need_clock_t
 
 #if !defined __time_t_defined && (defined _TIME_H || defined __need_time_t)
-#define	__time_t_defined	1
+# define __time_t_defined	1
 
-#include <bits/types.h>
+# include <bits/types.h>
 
 /* Returned by `time'.  */
 typedef __time_t time_t;
@@ -79,10 +79,9 @@ typedef __time_t time_t;
 #undef	__need_time_t
 
 
-#if	! defined __timespec_defined &&			\
-	((defined _TIME_H && defined __USE_POSIX) ||	\
-	 defined __need_timespec)
-#define	__timespec_defined	1
+#if !defined __timespec_defined && \
+    ((defined _TIME_H && defined __USE_POSIX) || defined __need_timespec)
+# define __timespec_defined	1
 
 /* POSIX.4 structure for a time value.  This is like a `struct timeval' but
    has nanoseconds instead of microseconds.  */
@@ -111,13 +110,13 @@ struct tm
   int tm_yday;			/* Days in year.[0-365]	*/
   int tm_isdst;			/* DST.		[-1/0/1]*/
 
-#ifdef	__USE_BSD
+# ifdef	__USE_BSD
   long int tm_gmtoff;		/* Seconds east of UTC.  */
   __const char *tm_zone;	/* Timezone abbreviation.  */
-#else
+# else
   long int __tm_gmtoff;		/* Seconds east of UTC.  */
   __const char *__tm_zone;	/* Timezone abbreviation.  */
-#endif
+# endif
 };
 
 #endif /* <time.h> included.  */
@@ -154,12 +153,12 @@ extern size_t strftime __P ((char *__restrict __s, size_t __maxsize,
 			     __const char *__restrict __format,
 			     __const struct tm *__restrict __tp));
 
-#ifdef __USE_XOPEN
+# ifdef __USE_XOPEN
 /* Parse S according to FORMAT and store binary time information in TP.
    The return value is a pointer to the first unparsed character in S.  */
 extern char *strptime __P ((__const char *__s, __const char *__fmt,
 			    struct tm *__tp));
-#endif
+# endif
 
 
 /* Return the `struct tm' representation of *TIMER
@@ -170,7 +169,7 @@ extern struct tm *gmtime __P ((__const time_t *__timer));
    of *TIMER in the local timezone.  */
 extern struct tm *localtime __P ((__const time_t *__timer));
 
-#if defined __USE_POSIX || defined __USE_MISC
+# if defined __USE_POSIX || defined __USE_MISC
 /* Return the `struct tm' representation of *TIMER in UTC,
    using *TP to store the result.  */
 extern struct tm *__gmtime_r __P ((__const time_t *__timer,
@@ -184,7 +183,7 @@ extern struct tm *__localtime_r __P ((__const time_t *__timer,
 				      struct tm *__tp));
 extern struct tm *localtime_r __P ((__const time_t *__timer,
 				    struct tm *__tp));
-#endif	/* POSIX or misc */
+# endif	/* POSIX or misc */
 
 /* Compute the `struct tm' representation of *T,
    offset OFFSET seconds east of UTC,
@@ -200,7 +199,7 @@ extern char *asctime __P ((__const struct tm *__tp));
 /* Equivalent to `asctime (localtime (timer))'.  */
 extern char *ctime __P ((__const time_t *__timer));
 
-#if defined __USE_POSIX || defined __USE_MISC
+# if defined __USE_POSIX || defined __USE_MISC
 /* Reentrant versions of the above functions.  */
 
 /* Return in BUF a string of the form "Day Mon dd hh:mm:ss yyyy\n"
@@ -210,7 +209,7 @@ extern char *asctime_r __P ((__const struct tm *__tp, char *__buf));
 
 /* Equivalent to `asctime_r (localtime_r (timer, *TMP*), buf)'.  */
 extern char *ctime_r __P ((__const time_t *__timer, char *__buf));
-#endif	/* POSIX or misc */
+# endif	/* POSIX or misc */
 
 
 /* Defined in localtime.c.  */
@@ -222,7 +221,7 @@ extern long int __timezone;	/* Seconds west of UTC.  */
    If TZ is not defined, a locale-dependent default is used.  */
 extern void __tzset __P ((void));
 
-#ifdef	__USE_POSIX
+# ifdef	__USE_POSIX
 /* Same as above.  */
 extern char *tzname[2];
 
@@ -231,27 +230,27 @@ extern char *tzname[2];
 extern long int __tzname_max __P ((void));
 
 extern void tzset __P ((void));
-#endif
+# endif
 
-#if defined __USE_SVID || defined __USE_XOPEN
+# if defined __USE_SVID || defined __USE_XOPEN
 extern int daylight;
 extern long int timezone;
-#endif
+# endif
 
-#ifdef __USE_SVID
+# ifdef __USE_SVID
 /* Set the system time to *WHEN.
    This call is restricted to the superuser.  */
 extern int stime __P ((__const time_t *__when));
-#endif
+# endif
 
 
 /* Nonzero if YEAR is a leap year (every 4 years,
    except every 100th isn't, and every 400th is).  */
-#define	__isleap(year)	\
+# define __isleap(year)	\
   ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
 
 
-#ifdef __USE_MISC
+# ifdef __USE_MISC
 /* Miscellaneous functions many Unices inherited from the public domain
    localtime package.  These are included only for compatibility.  */
 
@@ -263,19 +262,19 @@ extern time_t timelocal __P ((struct tm *__tp));
 
 /* Return the number of days in YEAR.  */
 extern int dysize __P ((int __year));
-#endif
+# endif
 
 
-#ifdef __USE_POSIX199309
+# ifdef __USE_POSIX199309
 /* Pause execution for a number of nanoseconds.  */
 extern int __nanosleep __P ((__const struct timespec *__requested_time,
 			     struct timespec *__remaining));
 extern int nanosleep __P ((__const struct timespec *__requested_time,
 			   struct timespec *__remaining));
-#endif
+# endif
 
 
-#ifdef __USE_XOPEN_EXTENDED
+# ifdef __USE_XOPEN_EXTENDED
 /* Set to one of the following values to indicate an error.
      1  the DATEMSK environment variable is null or undefined,
      2  the template file cannot be opened for reading,
@@ -294,9 +293,9 @@ extern int getdate_err;
    the environment variable DATEMSK are used.  In case of an error
    `getdate_err' is set.  */
 extern struct tm *getdate __P ((__const char *__string));
-#endif
+# endif
 
-#ifdef __USE_GNU
+# ifdef __USE_GNU
 /* Since `getdate' is not reentrant because of the use of `getdate_err'
    and the static buffer to return the result in, we provide a thread-safe
    variant.  The functionality is the same.  The result is returned in
@@ -304,7 +303,7 @@ extern struct tm *getdate __P ((__const char *__string));
    value is != 0 with the same values as given above for `getdate_err'.  */
 extern int __getdate_r __P ((__const char *__string, struct tm *__resbufp));
 extern int getdate_r __P ((__const char *__string, struct tm *__resbufp));
-#endif
+# endif
 
 
 __END_DECLS