1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00
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>.
This commit is contained in:
Ulrich Drepper
1997-09-30 17:10:40 +00:00
parent a2b08ee541
commit a5a0310d8e
138 changed files with 2418 additions and 1216 deletions

16
BUGS
View File

@ -1,7 +1,7 @@
List of known bugs (certainly very incomplete) 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 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 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 [ *] The rcmd() functions (more concrete: the handling of .rhosts) does
not support netgroups and wildcards (+). 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 Ulrich Drepper
drepper@cygnus.com drepper@cygnus.com

218
ChangeLog
View File

@ -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> 1997-09-27 01:14 Ulrich Drepper <drepper@cygnus.com>
* Makeconfig (extra-objs): Depend in before-compile. * Makeconfig (extra-objs): Depend in before-compile.

18
FAQ
View File

@ -90,6 +90,9 @@ please let me know.
[Q25] ``After installing glibc name resolving doesn't work properly.'' [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?'' [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 a point where it is stable. There are still lots of incompatible changes
made and the libc headers have to follow. 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. the required kernel version is 2.1.30.
@ -697,6 +700,18 @@ http://www-vt.uni-paderborn.de/~kukuk/linux/nisplus.html).
The NSS configuration file is usually the culprit. 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: Answers were given by:
@ -706,6 +721,7 @@ Answers were given by:
{HJL} H.J. Lu, <hjl@gnu.ai.mit.edu> {HJL} H.J. Lu, <hjl@gnu.ai.mit.edu>
{AJ} Andreas Jaeger, <aj@arthur.rhein-neckar.de> {AJ} Andreas Jaeger, <aj@arthur.rhein-neckar.de>
{EY} Eric Youngdale, <eric@andante.jic.com> {EY} Eric Youngdale, <eric@andante.jic.com>
{PB} Phil Blundell, <Philip.Blundell@pobox.com>
Local Variables: Local Variables:
mode:text mode:text

View File

@ -701,10 +701,6 @@ $(inst_slibdir)/libc.so: $(common-objpfx)libc.so
$(do-install-program) $(do-install-program)
endif endif
ifdef extra-objs
$(addprefix $(objpfx),$(extra-objs)): $(before-compile)
endif
ifneq (,$(versioned)) ifneq (,$(versioned))
# Produce three sets of rules as above for all the smaller versioned libraries. # Produce three sets of rules as above for all the smaller versioned libraries.

30
NEWS
View File

@ -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. Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
See the end for copying conditions. See the end for copying conditions.
@ -31,11 +31,31 @@ Version 2.1
* the new header <complex.h> contains definitions of the complex math * the new header <complex.h> contains definitions of the complex math
functions from ISO C 9X functions from ISO C 9X
* Thorsten Kukuk provided an implementation for NIS+, securelevel 0 and 1. * Thorsten Kukuk provided an implementation for NIS+, securelevel 0, 1 and 2.
The implementation for securelevel 2 will follow as soon as the Diffie-
Hellman patent expired.
* 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 Version 2.0.2

1
aclocal.m4 vendored
View File

@ -113,6 +113,7 @@ LD=`$CC -print-file-name=ld`
# Determine whether we are using GNU binutils. # Determine whether we are using GNU binutils.
AC_CACHE_CHECK(whether $AS is GNU as, libc_cv_prog_as_gnu, 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)]) [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 gnu_as=$libc_cv_prog_as_gnu
AC_CACHE_CHECK(whether $LD is GNU ld, libc_cv_prog_ld_gnu, AC_CACHE_CHECK(whether $LD is GNU ld, libc_cv_prog_ld_gnu,

136
configure vendored
View File

@ -27,8 +27,7 @@ ac_help="$ac_help
ac_help="$ac_help ac_help="$ac_help
--with-fp if using floating-point hardware [default=yes]" --with-fp if using floating-point hardware [default=yes]"
ac_help="$ac_help ac_help="$ac_help
--with-binutils=PATH specify location of binutils (as and ld) --with-binutils=PATH specify location of binutils (as and ld)"
path_binutils=$withval"
ac_help="$ac_help ac_help="$ac_help
--with-elf if using the ELF object format" --with-elf if using the ELF object format"
ac_help="$ac_help ac_help="$ac_help
@ -613,6 +612,8 @@ fi
# Check whether --with-binutils or --without-binutils was given. # Check whether --with-binutils or --without-binutils was given.
if test "${with_binutils+set}" = set; then if test "${with_binutils+set}" = set; then
withval="$with_binutils" withval="$with_binutils"
path_binutils=$withval
else
path_binutils='' path_binutils=''
fi fi
@ -754,7 +755,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi fi
echo $ac_n "checking host system type""... $ac_c" 1>&6 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 host_alias=$host
case "$host_alias" in case "$host_alias" in
@ -866,7 +867,7 @@ esac
# This can take a while to compute. # This can take a while to compute.
sysdep_dir=$srcdir/sysdeps sysdep_dir=$srcdir/sysdeps
echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6 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. # 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'`" 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" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh. # ./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 $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 test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
@ -1121,7 +1122,7 @@ if test "$INSTALL" = "${srcdir}/install-sh -c"; then
INSTALL='\$(..)./install-sh -c' INSTALL='\$(..)./install-sh -c'
fi fi
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1146,7 +1147,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args. # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2 set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1179,7 +1180,7 @@ test -n "$MSGFMT" || MSGFMT=":"
# Extract the first word of "gcc", so it can be a program name with args. # Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2 set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else 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. # Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2 set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1256,7 +1257,7 @@ fi
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 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 ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. # 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 cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1270 "configure" #line 1271 "configure"
#include "confdefs.h" #include "confdefs.h"
main(){return(0);} main(){return(0);}
EOF 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 ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler. # If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then if (./conftest; exit) 2>/dev/null; then
@ -1293,13 +1294,13 @@ else
cross_linkable=yes cross_linkable=yes
fi fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 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 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1308,7 +1309,7 @@ else
yes; yes;
#endif #endif
EOF 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 ac_cv_prog_gcc=yes
else else
ac_cv_prog_gcc=no ac_cv_prog_gcc=no
@ -1325,7 +1326,7 @@ if test $ac_cv_prog_gcc = yes; then
yes; yes;
#endif #endif
EOF 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 if test -z "$CFLAGS"; then
CFLAGS="-g -O2" CFLAGS="-g -O2"
fi fi
@ -1337,7 +1338,7 @@ else
fi fi
echo $ac_n "checking build system type""... $ac_c" 1>&6 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 build_alias=$build
case "$build_alias" in 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. # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2 set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1391,7 +1392,7 @@ done
fi fi
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 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. # On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then if test -n "$CPP" && test -d "$CPP"; then
CPP= CPP=
@ -1406,13 +1407,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser, # On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. # not just through cpp.
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1410 "configure" #line 1411 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" 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` ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
@ -1423,13 +1424,13 @@ else
rm -rf conftest* rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp" CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1427 "configure" #line 1428 "configure"
#include "confdefs.h" #include "confdefs.h"
#include <assert.h> #include <assert.h>
Syntax Error Syntax Error
EOF EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" 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` ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then if test -z "$ac_err"; then
: :
@ -1462,7 +1463,7 @@ LD=`$CC -print-file-name=ld`
# Determine whether we are using GNU binutils. # Determine whether we are using GNU binutils.
echo $ac_n "checking whether $AS is GNU as""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_prog_as_gnu'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1476,10 +1477,11 @@ fi
fi fi
echo "$ac_t""$libc_cv_prog_as_gnu" 1>&6 echo "$ac_t""$libc_cv_prog_as_gnu" 1>&6
rm -f a.out
gnu_as=$libc_cv_prog_as_gnu gnu_as=$libc_cv_prog_as_gnu
echo $ac_n "checking whether $LD is GNU ld""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_prog_ld_gnu'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1503,7 +1505,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. # 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 set dummy ${ac_tool_prefix}ar; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1534,7 +1536,7 @@ fi
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. # 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 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else 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. # Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2 set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1600,7 +1602,7 @@ fi
# Extract the first word of "bash", so it can be a program name with args. # Extract the first word of "bash", so it can be a program name with args.
set dummy bash; ac_word=$2 set dummy bash; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else 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. # Extract the first word of "ksh", so it can be a program name with args.
set dummy ksh; ac_word=$2 set dummy ksh; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1687,7 +1689,7 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args. # Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2 set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1722,7 +1724,7 @@ test -n "$PERL" || PERL="no"
echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1746,12 +1748,12 @@ EOF
fi fi
echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 1755 "configure" #line 1757 "configure"
#include "confdefs.h" #include "confdefs.h"
#define __need_size_t #define __need_size_t
#define __need_wchar_t #define __need_wchar_t
@ -1766,7 +1768,7 @@ size_t size; wchar_t wchar;
if (&size == NULL || &wchar == NULL) abort (); if (&size == NULL || &wchar == NULL) abort ();
; return 0; } ; return 0; }
EOF 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* rm -rf conftest*
libc_cv_friendly_stddef=yes libc_cv_friendly_stddef=yes
else else
@ -1785,7 +1787,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
fi fi
echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1808,7 +1810,7 @@ asm-CPPFLAGS = -P # The assembler can't grok cpp's # line directives."
fi fi
echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1838,7 +1840,7 @@ EOF
fi fi
echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1872,7 +1874,7 @@ EOF
fi fi
echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1891,7 +1893,7 @@ fi
echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6 echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
echo $ac_n "checking for ld --version-script""... $ac_c" 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 if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1910,7 +1912,7 @@ EOF
if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
-nostartfiles -nostdlib -nostartfiles -nostdlib
-Wl,--version-script,conftest.map -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 then
libc_cv_ld_version_script_option=yes libc_cv_ld_version_script_option=yes
else else
@ -1941,7 +1943,7 @@ fi
if test $elf = yes; then if test $elf = yes; then
echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1949,7 +1951,7 @@ else
.section foo_section .section foo_section
.previous .previous
EOF 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 libc_cv_asm_previous_directive=yes
else else
libc_cv_asm_previous_directive=no libc_cv_asm_previous_directive=no
@ -1965,7 +1967,7 @@ EOF
else else
echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -1973,7 +1975,7 @@ else
.pushsection foo_section .pushsection foo_section
.popsection .popsection
EOF 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 libc_cv_asm_popsection_directive=yes
else else
libc_cv_asm_popsection_directive=no libc_cv_asm_popsection_directive=no
@ -1993,12 +1995,12 @@ fi
if test $elf != yes; then if test $elf != yes; then
echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2002 "configure" #line 2004 "configure"
#include "confdefs.h" #include "confdefs.h"
int main() { int main() {
@ -2007,7 +2009,7 @@ asm (".section .init");
asm (".text"); asm (".text");
; return 0; } ; return 0; }
EOF 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* rm -rf conftest*
libc_cv_have_initfini=yes libc_cv_have_initfini=yes
else else
@ -2035,19 +2037,19 @@ if test $elf = yes; then
else else
if test $ac_cv_prog_cc_works = yes; then if test $ac_cv_prog_cc_works = yes; then
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2044 "configure" #line 2046 "configure"
#include "confdefs.h" #include "confdefs.h"
asm ("_glibc_foobar:"); asm ("_glibc_foobar:");
int main() { int main() {
glibc_foobar (); glibc_foobar ();
; return 0; } ; return 0; }
EOF 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* rm -rf conftest*
libc_cv_asm_underscores=yes libc_cv_asm_underscores=yes
else else
@ -2062,17 +2064,17 @@ fi
echo "$ac_t""$libc_cv_asm_underscores" 1>&6 echo "$ac_t""$libc_cv_asm_underscores" 1>&6
else else
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 2071 "configure" #line 2073 "configure"
#include "confdefs.h" #include "confdefs.h"
void underscore_test(void) { void underscore_test(void) {
return; } return; }
EOF 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 if grep _underscore_test conftest* >/dev/null; then
rm -f conftest* rm -f conftest*
libc_cv_asm_underscores=yes libc_cv_asm_underscores=yes
@ -2105,7 +2107,7 @@ if test $elf = yes; then
libc_cv_asm_weakext_directive=no libc_cv_asm_weakext_directive=no
else else
echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -2128,7 +2130,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
if test $libc_cv_asm_weak_directive = no; then if test $libc_cv_asm_weak_directive = no; then
echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -2165,7 +2167,7 @@ EOF
fi fi
echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -2176,7 +2178,7 @@ __throw () {}
EOF EOF
if { ac_try='${CC-cc} $CFLAGS if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -Wl,--no-whole-archive -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 libc_cv_ld_no_whole_archive=yes
else else
libc_cv_ld_no_whole_archive=no 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_t""$libc_cv_ld_no_whole_archive" 1>&6
echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 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 if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -2198,7 +2200,7 @@ __throw () {}
EOF EOF
if { ac_try='${CC-cc} $CFLAGS if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -fno-exceptions -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 libc_cv_gcc_no_exceptions=yes
else else
libc_cv_gcc_no_exceptions=no libc_cv_gcc_no_exceptions=no
@ -2209,12 +2211,12 @@ fi
echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6 echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6
echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 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 if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
cat > conftest.c <<EOF cat > conftest.c <<EOF
#line 2218 "configure" #line 2220 "configure"
static char __EH_FRAME_BEGIN__; static char __EH_FRAME_BEGIN__;
_start () _start ()
{ {
@ -2234,7 +2236,7 @@ abort () {}
EOF EOF
if { ac_try='${CC-cc} $CFLAGS if { ac_try='${CC-cc} $CFLAGS
-nostdlib -nostartfiles -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 libc_cv_gcc_dwarf2_unwind_info=yes
else else
libc_cv_gcc_dwarf2_unwind_info=no libc_cv_gcc_dwarf2_unwind_info=no
@ -2292,7 +2294,7 @@ if test "$uname" = "sysdeps/generic"; then
fi fi
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -2314,7 +2316,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
uname_release="$libc_cv_uname_release" uname_release="$libc_cv_uname_release"
echo $ac_n "checking OS version for uname""... $ac_c" 1>&6 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 if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6 echo $ac_n "(cached) $ac_c" 1>&6
else else
@ -2336,7 +2338,7 @@ else
fi fi
echo $ac_n "checking stdio selection""... $ac_c" 1>&6 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 case $stdio in
libio) cat >> confdefs.h <<\EOF libio) cat >> confdefs.h <<\EOF
@ -2348,7 +2350,7 @@ esac
echo "$ac_t""$stdio" 1>&6 echo "$ac_t""$stdio" 1>&6
echo $ac_n "checking ldap selection""... $ac_c" 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 case $add_ons in
*ldap*) *ldap*)

View File

@ -37,7 +37,7 @@ AC_ARG_WITH(fp, dnl
[ --with-fp if using floating-point hardware [default=yes]], [ --with-fp if using floating-point hardware [default=yes]],
with_fp=$withval, with_fp=yes) with_fp=$withval, with_fp=yes)
AC_ARG_WITH(binutils, dnl 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='') path_binutils=$withval, path_binutils='')
AC_ARG_WITH(elf, dnl AC_ARG_WITH(elf, dnl
--with-elf if using the ELF object format, --with-elf if using the ELF object format,

View File

@ -32,9 +32,6 @@ csu-dummies = $(filter-out $(start-installed-name),crt1.o Mcrt1.o)
extra-objs = start.o gmon-start.o \ extra-objs = start.o gmon-start.o \
$(start-installed-name) g$(start-installed-name) \ $(start-installed-name) g$(start-installed-name) \
$(csu-dummies) $(csu-dummies)
ifeq ($(elf),yes)
before-compile = $(objpfx)abi-tag.h
endif
omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \ omit-deps = $(patsubst %.o,%,$(start-installed-name) g$(start-installed-name) \
$(csu-dummies)) $(csu-dummies))
install-lib = $(start-installed-name) g$(start-installed-name) \ 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 include ../Makeconfig
ifeq ($(elf),yes)
before-compile = $(objpfx)abi-tag.h
endif
ifeq ($(have-initfini),yes) ifeq ($(have-initfini),yes)

View File

@ -19,7 +19,7 @@
# #
# Sub-makefile for libdb. # 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. # with minimal changes.
# #

View File

@ -47,7 +47,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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 * 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, * start with, and I'm not sure what undoing a statistics update means,
* anyway. * anyway.
*/ */

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -21,12 +21,11 @@ static const char sccsid[] = "@(#)bt_conv.c 10.4 (Sleepycat) 9/3/97";
#include "btree.h" #include "btree.h"
/* /*
* __bam_pgin, __bam_pgout -- * __bam_pgin --
* Convert host-specific page layout to/from the host-independent * Convert host-specific page layout from the host-independent format
* format stored on disk. * stored on disk.
* *
* PUBLIC: int __bam_pgin __P((db_pgno_t, void *, DBT *)); * PUBLIC: int __bam_pgin __P((db_pgno_t, void *, DBT *));
* PUBLIC: int __bam_pgout __P((db_pgno_t, void *, DBT *));
*/ */
int int
__bam_pgin(pg, pp, cookie) __bam_pgin(pg, pp, cookie)
@ -39,9 +38,17 @@ __bam_pgin(pg, pp, cookie)
pginfo = (DB_PGINFO *)cookie->data; pginfo = (DB_PGINFO *)cookie->data;
if (!pginfo->needswap) if (!pginfo->needswap)
return (0); 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 int
__bam_pgout(pg, pp, cookie) __bam_pgout(pg, pp, cookie)
db_pgno_t pg; db_pgno_t pg;
@ -53,7 +60,8 @@ __bam_pgout(pg, pp, cookie)
pginfo = (DB_PGINFO *)cookie->data; pginfo = (DB_PGINFO *)cookie->data;
if (!pginfo->needswap) if (!pginfo->needswap)
return (0); 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));
} }
/* /*

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -81,7 +81,10 @@ __bam_cursor(dbp, txn, dbcp)
dbc->c_get = __bam_c_get; dbc->c_get = __bam_c_get;
dbc->c_put = __bam_c_put; 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); DB_THREAD_LOCK(dbp);
TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links); TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links);
DB_THREAD_UNLOCK(dbp); DB_THREAD_UNLOCK(dbp);
@ -99,31 +102,53 @@ __bam_c_close(dbc)
DBC *dbc; DBC *dbc;
{ {
DB *dbp; DB *dbp;
CURSOR *cp;
int ret; int ret;
DEBUG_LWRITE(dbc->dbp, dbc->txn, "bam_c_close", NULL, NULL, 0); DEBUG_LWRITE(dbc->dbp, dbc->txn, "bam_c_close", NULL, NULL, 0);
GETHANDLE(dbc->dbp, dbc->txn, &dbp, ret); 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; cp = dbc->internal;
/* If a cursor key was deleted do the actual deletion. */ /* If a cursor key was deleted, perform the actual deletion. */
ret = F_ISSET(cp, C_DELETED) ? __bam_c_physdel(dbp, cp, NULL) : 0; ret = F_ISSET(cp, C_DELETED) ? __bam_c_physdel(dbp, cp, NULL) : 0;
/* Discard any lock if we're not inside a transaction. */ /* 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); (void)__BT_TLPUT(dbp, cp->lock);
/* Remove the cursor from the queue. */ /*
DB_THREAD_LOCK(dbp); * All cursors are queued from the master DB structure. Remove the
TAILQ_REMOVE(&dbp->curs_queue, dbc, links); * cursor from that queue.
DB_THREAD_UNLOCK(dbp); */
DB_THREAD_LOCK(dbc->dbp);
TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
DB_THREAD_UNLOCK(dbc->dbp);
/* Discard the structures. */ /* Discard the structures. */
FREE(cp, sizeof(CURSOR)); FREE(dbc->internal, sizeof(CURSOR));
FREE(dbc, sizeof(DBC)); FREE(dbc, sizeof(DBC));
PUTHANDLE(dbp);
return (ret); return (ret);
} }
@ -235,27 +260,22 @@ __bam_get(argdbp, txn, key, data, flags)
if ((ret = __db_getchk(argdbp, key, data, flags)) != 0) if ((ret = __db_getchk(argdbp, key, data, flags)) != 0)
return (ret); return (ret);
/* Build a cursor. */ /* Build an internal cursor. */
memset(&cp, 0, sizeof(cp)); memset(&cp, 0, sizeof(cp));
cp.dbc = &dbc; cp.dbc = &dbc;
cp.pgno = cp.dpgno = PGNO_INVALID; cp.pgno = cp.dpgno = PGNO_INVALID;
cp.lock = LOCK_INVALID; cp.lock = LOCK_INVALID;
cp.flags = C_INTERNAL;
/* Build an external cursor. */
memset(&dbc, 0, sizeof(dbc)); memset(&dbc, 0, sizeof(dbc));
dbc.dbp = argdbp; dbc.dbp = argdbp;
dbc.txn = txn; dbc.txn = txn;
dbc.internal = &cp; dbc.internal = &cp;
/* Get the key. */ /* Get the key. */
if ((ret = __bam_c_get(&dbc, return(__bam_c_get(&dbc,
key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET)) != 0) key, data, LF_ISSET(DB_SET_RECNO) ? DB_SET_RECNO : DB_SET));
return (ret);
/* Discard any lock, the cursor didn't really exist. */
if (cp.lock != LOCK_INVALID)
(void)__BT_TLPUT(argdbp, cp.lock);
return (0);
} }
/* /*
@ -275,8 +295,7 @@ __bam_c_get(dbc, key, data, flags)
int exact, ret; int exact, ret;
DEBUG_LREAD(dbc->dbp, dbc->txn, "bam_c_get", DEBUG_LREAD(dbc->dbp, dbc->txn, "bam_c_get",
flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, flags == DB_SET || flags == DB_SET_RANGE ? key : NULL, NULL, flags);
NULL, flags);
cp = dbc->internal; cp = dbc->internal;
@ -399,6 +418,10 @@ __bam_c_get(dbc, key, data, flags)
/* Release the pinned page. */ /* Release the pinned page. */
ret = memp_fput(dbp->mpf, cp->page, 0); 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; ++t->lstat.bt_get;
if (0) { if (0) {
@ -1472,8 +1495,7 @@ __bam_c_physdel(dbp, cp, h)
* empty the current page of duplicates, we don't need to * empty the current page of duplicates, we don't need to
* touch the parent page. * touch the parent page.
*/ */
if (PREV_PGNO(h) != PGNO_INVALID || if (prev_pgno != PGNO_INVALID || (h != NULL && pgno == h->pgno))
(h != NULL && pgno == h->pgno))
goto done; goto done;
/* /*

View File

@ -47,7 +47,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -99,7 +99,7 @@ __bam_put(argdbp, txn, key, data, flags)
t = dbp->internal; t = dbp->internal;
retry: /* 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. * leaves the returned page pinned.
*/ */
if ((ret = __bam_lookup(dbp, key, &exact)) != 0) { if ((ret = __bam_lookup(dbp, key, &exact)) != 0) {

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -298,11 +298,10 @@ __bam_split_recover(logp, dbtp, lsnp, redo, info)
goto done; goto done;
/* Allocate and initialize new left/right child pages. */ /* Allocate and initialize new left/right child pages. */
if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) if ((_lp = (PAGE *)malloc(file_dbp->pgsize)) == NULL ||
goto nomem; (_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) {
if ((_rp = (PAGE *)malloc(file_dbp->pgsize)) == NULL) { ret = ENOMEM;
nomem: __set_errno(ENOMEM); __db_err(file_dbp->dbenv, "%s", strerror(ret));
__db_err(file_dbp->dbenv, "%s", strerror(errno));
goto out; goto out;
} }
if (rootsplit) { if (rootsplit) {
@ -668,7 +667,7 @@ __bam_cadjust_recover(logp, dbtp, lsnp, redo, info)
REC_INTRO(__bam_cadjust_read); REC_INTRO(__bam_cadjust_read);
if ((ret = memp_fget(mpf, &argp->pgno, 0, &pagep)) != 0) { 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; pagep = NULL;
goto out; goto out;
} }

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -76,7 +76,7 @@ __ram_open(dbp, type, dbinfo)
/* Allocate and initialize the private RECNO structure. */ /* Allocate and initialize the private RECNO structure. */
if ((rp = (RECNO *)calloc(1, sizeof(*rp))) == NULL) if ((rp = (RECNO *)calloc(1, sizeof(*rp))) == NULL)
return (errno); return (ENOMEM);
if (dbinfo != NULL) { 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. */ /* If we allocated room for key/data return, discard it. */
t = dbp->internal; t = dbp->internal;
if (t->bt_rkey.data != NULL) if (t != NULL && t->bt_rkey.data != NULL)
free(t->bt_rkey.data); free(t->bt_rkey.data);
FREE(rp, sizeof(*rp)); FREE(rp, sizeof(*rp));
@ -193,7 +193,10 @@ __ram_cursor(dbp, txn, dbcp)
dbc->c_get = __ram_c_get; dbc->c_get = __ram_c_get;
dbc->c_put = __ram_c_put; 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); DB_THREAD_LOCK(dbp);
TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links); TAILQ_INSERT_HEAD(&dbp->curs_queue, dbc, links);
DB_THREAD_UNLOCK(dbp); DB_THREAD_UNLOCK(dbp);
@ -382,16 +385,29 @@ static int
__ram_c_close(dbc) __ram_c_close(dbc)
DBC *dbc; DBC *dbc;
{ {
DB *dbp;
DEBUG_LWRITE(dbc->dbp, dbc->txn, "ram_c_close", NULL, NULL, 0); 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); * __ram_c_iclose --
TAILQ_REMOVE(&dbp->curs_queue, dbc, links); * Close a single cursor -- internal version.
DB_THREAD_UNLOCK(dbp); *
* 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. */ /* Discard the structures. */
FREE(dbc->internal, sizeof(RCURSOR)); FREE(dbc->internal, sizeof(RCURSOR));

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
PREFIX bam PREFIX bam

View File

@ -18,7 +18,6 @@ static const char sccsid[] = "@(#)getlong.c 10.2 (Sleepycat) 5/1/97";
#endif #endif
#include "db.h" #include "db.h"
#include "db_int.h"
#include "clib_ext.h" #include "clib_ext.h"
/* /*

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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_ #ifndef _DB_H_
@ -67,8 +67,8 @@
#define DB_VERSION_MAJOR 2 #define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 3 #define DB_VERSION_MINOR 3
#define DB_VERSION_PATCH 6 #define DB_VERSION_PATCH 10
#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.6: (9/4/97)" #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_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset 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. */ /* DB access method description structure. */
struct __db { struct __db {
void *mutex; /* Synchronization for free threading */ void *mutexp; /* Synchronization for free threading */
DBTYPE type; /* DB access method. */ DBTYPE type; /* DB access method. */
DB_ENV *dbenv; /* DB_ENV structure. */ DB_ENV *dbenv; /* DB_ENV structure. */
DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */ DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */
@ -641,11 +641,11 @@ extern "C" {
#endif #endif
int memp_close __P((DB_MPOOL *)); int memp_close __P((DB_MPOOL *));
int memp_fclose __P((DB_MPOOLFILE *)); 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 memp_fopen __P((DB_MPOOL *, const char *,
int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **)); int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **));
int memp_fput __P((DB_MPOOLFILE *, void *, unsigned long)); int memp_fput __P((DB_MPOOLFILE *, void *, int));
int memp_fset __P((DB_MPOOLFILE *, void *, unsigned long)); int memp_fset __P((DB_MPOOLFILE *, void *, int));
int memp_fsync __P((DB_MPOOLFILE *)); int memp_fsync __P((DB_MPOOLFILE *));
int memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **)); int memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **));
int memp_register __P((DB_MPOOL *, int, int memp_register __P((DB_MPOOL *, int,
@ -698,7 +698,7 @@ extern "C" {
#endif #endif
int txn_abort __P((DB_TXN *)); int txn_abort __P((DB_TXN *));
int txn_begin __P((DB_TXNMGR *, DB_TXN *, 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_commit __P((DB_TXN *));
int txn_close __P((DB_TXNMGR *)); int txn_close __P((DB_TXNMGR *));
u_int32_t txn_id __P((DB_TXN *)); u_int32_t txn_id __P((DB_TXN *));

View File

@ -44,7 +44,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -137,7 +137,13 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
} }
dbp->dbenv = dbenv; 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) { if (dbinfo != NULL) {
/* /*
* !!! * !!!
@ -160,23 +166,6 @@ db_open(fname, type, flags, mode, dbenv, dbinfo, dbpp)
F_SET(dbp, DB_RE_SNAPSHOT); 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 * Always set the master and initialize the queues, so we can
* use these fields without checking the thread bit. * 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 * Set based on the dbenv fields, although no logging or transactions
* are possible for temporary files. * are possible for temporary files.
*/ */
if (dbp->dbenv != NULL) { if (dbenv != NULL) {
if (dbenv->lk_info != NULL) if (dbenv->lk_info != NULL)
F_SET(dbp, DB_AM_LOCKING); F_SET(dbp, DB_AM_LOCKING);
if (fname != NULL && dbenv->lg_info != NULL) 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. * sizes, we limit the default pagesize to 16K.
*/ */
if (dbp->pgsize == 0) { if (dbp->pgsize == 0) {
if ((ret = __db_stat(dbp->dbenv, if ((ret =
real_name, fd, NULL, &io)) != 0) __db_stat(dbenv, real_name, fd, NULL, &io)) != 0)
goto err; goto err;
if (io < 512) if (io < 512)
io = 512; io = 512;
@ -573,6 +562,15 @@ empty: /*
0, &pgcookie, dbp->lock.fileid, &dbp->mpf)) != 0) 0, &pgcookie, dbp->lock.fileid, &dbp->mpf)) != 0)
goto err; 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. */ /* Get a log file id. */
if (F_ISSET(dbp, DB_AM_LOGGING) && if (F_ISSET(dbp, DB_AM_LOGGING) &&
(ret = log_register(dbenv->lg_info, (ret = log_register(dbenv->lg_info,
@ -672,7 +670,9 @@ db_close(dbp, flags)
DB *tdbp; DB *tdbp;
int ret, t_ret; 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. */ /* Sync the underlying file. */
if (!LF_ISSET(DB_NOSYNC) && if (!LF_ISSET(DB_NOSYNC) &&
@ -685,10 +685,26 @@ db_close(dbp, flags)
*/ */
for (tdbp = LIST_FIRST(&dbp->handleq); for (tdbp = LIST_FIRST(&dbp->handleq);
tdbp != NULL; tdbp = LIST_NEXT(tdbp, links)) { tdbp != NULL; tdbp = LIST_NEXT(tdbp, links)) {
while ((dbc = TAILQ_FIRST(&tdbp->curs_queue)) != NULL) while ((dbc = TAILQ_FIRST(&tdbp->curs_queue)) != NULL)
if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0) switch (tdbp->type) {
case DB_BTREE:
if ((t_ret =
__bam_c_iclose(tdbp, dbc)) != 0 && ret == 0)
ret = t_ret; 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) { switch (tdbp->type) {
case DB_BTREE: case DB_BTREE:
@ -706,7 +722,6 @@ db_close(dbp, flags)
default: default:
abort(); abort();
} }
} }
/* Sync the memory pool. */ /* Sync the memory pool. */
@ -722,10 +737,6 @@ db_close(dbp, flags)
(t_ret = memp_close(dbp->mp)) != 0 && ret == 0) (t_ret = memp_close(dbp->mp)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
/* Discard the mutex. */
if (dbp->mutex != NULL)
FREE(dbp->mutex, sizeof(db_mutex_t));
/* Discard the log file id. */ /* Discard the log file id. */
if (F_ISSET(dbp, DB_AM_LOGGING)) if (F_ISSET(dbp, DB_AM_LOGGING))
(void)log_unregister(dbp->dbenv->lg_info, dbp->log_fileid); (void)log_unregister(dbp->dbenv->lg_info, dbp->log_fileid);

View File

@ -44,7 +44,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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_swap.h"
#include "db_am.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_pgin __P((db_pgno_t, size_t, void *));
* PUBLIC: int __db_pgout __P((db_pgno_t, void *));
*/ */
int int
__db_pgin(pg, pp) __db_pgin(pg, pagesize, pp)
db_pgno_t pg; db_pgno_t pg;
size_t pagesize;
void *pp; 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 int
__db_pgout(pg, pp) __db_pgout(pg, pagesize, pp)
db_pgno_t pg; db_pgno_t pg;
size_t pagesize;
void *pp; 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. * Actually convert a page.
*/ */
static int static int
__db_convert(pg, pp, pgin) __db_convert(pg, pp, pagesize, pgin)
db_pgno_t pg; /* Unused, but left for the future. */ db_pgno_t pg; /* Unused, but left for the future. */
void *pp; void *pp;
size_t pagesize;
int pgin; int pgin;
{ {
BINTERNAL *bi; BINTERNAL *bi;
BKEYDATA *bk; BKEYDATA *bk;
BOVERFLOW *bo; BOVERFLOW *bo;
HKEYDATA *hk;
PAGE *h; PAGE *h;
RINTERNAL *ri; RINTERNAL *ri;
db_indx_t i; db_indx_t i, len, tmp;
u_int8_t *p; u_int8_t *p, *end;
h = pp; h = pp;
if (pgin) { if (pgin) {
@ -118,24 +124,42 @@ __db_convert(pg, pp, pgin)
if (pgin) if (pgin)
M_16_SWAP(h->inp[i]); M_16_SWAP(h->inp[i]);
hk = GET_HKEYDATA(h, i); switch (HPAGE_TYPE(h, i)) {
switch (hk->type) {
case H_KEYDATA: case H_KEYDATA:
break; break;
case H_DUPLICATE: case H_DUPLICATE:
case H_OFFPAGE: len = LEN_HKEYDATA(h, pagesize, i);
p = (u_int8_t *)hk + sizeof(u_int8_t); p = HKEYDATA_DATA(P_ENTRY(h, i));
++p; for (end = p + len; p < end;) {
SWAP32(p); /* tlen */ 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 */ SWAP32(p); /* pgno */
SWAP16(p); /* offset */ break;
SWAP16(p); /* len */ case H_OFFPAGE:
p = HOFFPAGE_PGNO(P_ENTRY(h, i));
SWAP32(p); /* pgno */
SWAP32(p); /* tlen */
break; 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; break;
case P_LBTREE: case P_LBTREE:
case P_LRECNO: case P_LRECNO:

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -184,7 +184,7 @@ __db_prbtree(dbp)
BTMETA *mp; BTMETA *mp;
BTREE *t; BTREE *t;
DB_LOCK lock; DB_LOCK lock;
EPG *sp; EPG *epg;
FILE *fp; FILE *fp;
RECNO *rp; RECNO *rp;
db_pgno_t i; db_pgno_t i;
@ -230,8 +230,8 @@ __db_prbtree(dbp)
(u_long)rp->re_emap, (u_long)rp->re_msize); (u_long)rp->re_emap, (u_long)rp->re_msize);
} }
(void)fprintf(fp, "stack:"); (void)fprintf(fp, "stack:");
for (sp = t->bt_stack; sp < t->bt_sp; ++sp) for (epg = t->bt_stack; epg < t->bt_sp; ++epg)
(void)fprintf(fp, " %lu", (u_long)sp->page->pgno); (void)fprintf(fp, " %lu", (u_long)epg->page->pgno);
(void)fprintf(fp, "\n"); (void)fprintf(fp, "\n");
(void)fprintf(fp, "ovflsize: %lu\n", (u_long)t->bt_ovflsize); (void)fprintf(fp, "ovflsize: %lu\n", (u_long)t->bt_ovflsize);
(void)fflush(fp); (void)fflush(fp);
@ -367,20 +367,15 @@ __db_prpage(h, all)
{ {
BINTERNAL *bi; BINTERNAL *bi;
BKEYDATA *bk; BKEYDATA *bk;
HKEYDATA *hkd;
HOFFPAGE a_hkd; HOFFPAGE a_hkd;
FILE *fp; FILE *fp;
RINTERNAL *ri; RINTERNAL *ri;
db_indx_t dlen, len, i; db_indx_t dlen, len, i;
db_pgno_t pgno; db_pgno_t pgno;
u_int8_t *p;
int deleted, ret; int deleted, ret;
const char *s; const char *s;
u_int8_t *ep, *hk, *p;
bi = NULL; /* XXX: Shut the compiler up. */ void *sp;
bk = NULL;
hkd = NULL;
ri = NULL;
fp = __db_prinit(NULL); fp = __db_prinit(NULL);
@ -450,22 +445,18 @@ __db_prpage(h, all)
deleted = 0; deleted = 0;
switch (TYPE(h)) { switch (TYPE(h)) {
case P_HASH: case P_HASH:
hkd = GET_HKEYDATA(h, i);
break;
case P_IBTREE: case P_IBTREE:
bi = GET_BINTERNAL(h, i);
break;
case P_IRECNO: case P_IRECNO:
ri = GET_RINTERNAL(h, i); sp = P_ENTRY(h, i);
break; break;
case P_LBTREE: case P_LBTREE:
bk = GET_BKEYDATA(h, i); sp = P_ENTRY(h, i);
deleted = i % 2 == 0 && deleted = i % 2 == 0 &&
B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type); B_DISSET(GET_BKEYDATA(h, i + O_INDX)->type);
break; break;
case P_LRECNO: case P_LRECNO:
case P_DUPLICATE: case P_DUPLICATE:
bk = GET_BKEYDATA(h, i); sp = P_ENTRY(h, i);
deleted = B_DISSET(GET_BKEYDATA(h, i)->type); deleted = B_DISSET(GET_BKEYDATA(h, i)->type);
break; break;
default: default:
@ -478,11 +469,11 @@ __db_prpage(h, all)
deleted ? "D" : " ", (u_long)i, (u_long)h->inp[i]); deleted ? "D" : " ", (u_long)i, (u_long)h->inp[i]);
switch (TYPE(h)) { switch (TYPE(h)) {
case P_HASH: case P_HASH:
switch (hkd->type) { hk = sp;
switch (HPAGE_PTYPE(hk)) {
case H_OFFDUP: case H_OFFDUP:
memcpy(&pgno, memcpy(&pgno,
(u_int8_t *)hkd + SSZ(HOFFDUP, pgno), HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
sizeof(db_pgno_t));
fprintf(fp, fprintf(fp,
"%4lu [offpage dups]\n", (u_long)pgno); "%4lu [offpage dups]\n", (u_long)pgno);
break; break;
@ -499,7 +490,8 @@ __db_prpage(h, all)
len = 1; len = 1;
fprintf(fp, "Duplicates:\n"); 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)); memcpy(&dlen, p, sizeof(db_indx_t));
p += sizeof(db_indx_t); p += sizeof(db_indx_t);
fprintf(fp, "\t\t"); fprintf(fp, "\t\t");
@ -509,13 +501,13 @@ __db_prpage(h, all)
break; break;
case H_KEYDATA: case H_KEYDATA:
if (i != 0) if (i != 0)
__db_pr(hkd->data, __db_pr(HKEYDATA_DATA(hk),
LEN_HKEYDATA(h, 0, i)); LEN_HKEYDATA(h, 0, i));
else else
fprintf(fp, "%s\n", hkd->data); fprintf(fp, "%s\n", HKEYDATA_DATA(hk));
break; break;
case H_OFFPAGE: case H_OFFPAGE:
memcpy(&a_hkd, hkd, HOFFPAGE_SIZE); memcpy(&a_hkd, hk, HOFFPAGE_SIZE);
fprintf(fp, fprintf(fp,
"overflow: total len: %4lu page: %4lu\n", "overflow: total len: %4lu page: %4lu\n",
(u_long)a_hkd.tlen, (u_long)a_hkd.pgno); (u_long)a_hkd.tlen, (u_long)a_hkd.pgno);
@ -523,6 +515,7 @@ __db_prpage(h, all)
} }
break; break;
case P_IBTREE: case P_IBTREE:
bi = sp;
fprintf(fp, "count: %4lu pgno: %4lu ", fprintf(fp, "count: %4lu pgno: %4lu ",
(u_long)bi->nrecs, (u_long)bi->pgno); (u_long)bi->nrecs, (u_long)bi->pgno);
switch (B_TYPE(bi->type)) { switch (B_TYPE(bi->type)) {
@ -541,12 +534,14 @@ __db_prpage(h, all)
} }
break; break;
case P_IRECNO: case P_IRECNO:
ri = sp;
fprintf(fp, "entries %4lu pgno %4lu\n", fprintf(fp, "entries %4lu pgno %4lu\n",
(u_long)ri->nrecs, (u_long)ri->pgno); (u_long)ri->nrecs, (u_long)ri->pgno);
break; break;
case P_LBTREE: case P_LBTREE:
case P_LRECNO: case P_LRECNO:
case P_DUPLICATE: case P_DUPLICATE:
bk = sp;
switch (B_TYPE(bk->type)) { switch (B_TYPE(bk->type)) {
case B_KEYDATA: case B_KEYDATA:
__db_pr(bk->data, bk->len); __db_pr(bk->data, bk->len);
@ -582,13 +577,9 @@ __db_isbad(h, die)
{ {
BINTERNAL *bi; BINTERNAL *bi;
BKEYDATA *bk; BKEYDATA *bk;
HKEYDATA *hkd;
FILE *fp; FILE *fp;
db_indx_t i; db_indx_t i;
int type;
bi = NULL; /* XXX: Shut the compiler up. */
bk = NULL;
hkd = NULL;
fp = __db_prinit(NULL); fp = __db_prinit(NULL);
@ -618,13 +609,13 @@ __db_isbad(h, die)
} }
switch (TYPE(h)) { switch (TYPE(h)) {
case P_HASH: case P_HASH:
hkd = GET_HKEYDATA(h, i); type = HPAGE_TYPE(h, i);
if (hkd->type != H_OFFDUP && if (type != H_OFFDUP &&
hkd->type != H_DUPLICATE && type != H_DUPLICATE &&
hkd->type != H_KEYDATA && type != H_KEYDATA &&
hkd->type != H_OFFPAGE) { type != H_OFFPAGE) {
fprintf(fp, "ILLEGAL HASH TYPE: %lu\n", fprintf(fp, "ILLEGAL HASH TYPE: %lu\n",
(u_long)hkd->type); (u_long)type);
goto bad; goto bad;
} }
break; break;

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -46,18 +46,19 @@ __db_ret(dbp, h, indx, dbt, memp, memsize)
HOFFPAGE ho; HOFFPAGE ho;
BOVERFLOW *bo; BOVERFLOW *bo;
u_int32_t len; u_int32_t len;
void *data, *hk; u_int8_t *hk;
void *data;
switch (TYPE(h)) { switch (TYPE(h)) {
case P_HASH: case P_HASH:
hk = P_ENTRY(h, indx); hk = P_ENTRY(h, indx);
if (((HKEYDATA *)hk)->type == H_OFFPAGE) { if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
memcpy(&ho, hk, sizeof(HOFFPAGE)); memcpy(&ho, hk, sizeof(HOFFPAGE));
return (__db_goff(dbp, dbt, return (__db_goff(dbp, dbt,
ho.tlen, ho.pgno, memp, memsize)); ho.tlen, ho.pgno, memp, memsize));
} }
len = LEN_HKEYDATA(h, dbp->pgsize, indx); len = LEN_HKEYDATA(h, dbp->pgsize, indx);
data = ((HKEYDATA *)hk)->data; data = HKEYDATA_DATA(hk);
break; break;
case P_DUPLICATE: case P_DUPLICATE:
case P_LBTREE: case P_LBTREE:

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -42,7 +42,7 @@ __db_gethandle(dbp, am_func, dbpp)
DB *ret_dbp; DB *ret_dbp;
int ret, t_ret; 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) dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
return (ret); return (ret);
@ -75,7 +75,7 @@ err: if (ret_dbp != NULL)
FREE(ret_dbp, sizeof(*ret_dbp)); FREE(ret_dbp, sizeof(*ret_dbp));
} }
if ((t_ret = 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; ret = t_ret;
return (ret); return (ret);
} }
@ -94,13 +94,13 @@ __db_puthandle(dbp)
int ret; int ret;
master = dbp->master; 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) dbp->dbenv == NULL ? NULL : dbp->dbenv->db_yield)) != 0)
return (ret); return (ret);
LIST_INSERT_HEAD(&master->handleq, dbp, links); 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));
} }
/* /*

View File

@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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_ #ifndef _DB_185_H_
@ -70,6 +70,14 @@
#endif
/*
* XXX
* SGI/IRIX already has a pgno_t.
*/
#ifdef sgi
#define pgno_t db_pgno_t
#endif #endif
#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */ #define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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_ #ifndef _DB_INTERNAL_H_
@ -25,12 +25,6 @@
#define DB_MINCACHE 10 /* Minimum cached pages */ #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 * 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 * separate macro, as we've had to cast the pointer to different integral
@ -183,11 +177,11 @@ typedef struct _db_mutex_t {
/* Lock/unlock a DB thread. */ /* Lock/unlock a DB thread. */
#define DB_THREAD_LOCK(dbp) \ #define DB_THREAD_LOCK(dbp) \
(F_ISSET(dbp, DB_AM_THREAD) ? \ (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) (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
#define DB_THREAD_UNLOCK(dbp) \ #define DB_THREAD_UNLOCK(dbp) \
(F_ISSET(dbp, DB_AM_THREAD) ? \ (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. */ /* Btree/recno local statistics structure. */
struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT; struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT;
@ -311,14 +305,6 @@ typedef struct __dbpginfo {
/******************************************************* /*******************************************************
* Transactions and recovery. * 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 * 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 * into the lock regions. Since the RLAYOUT structure begins all regions, an

View File

@ -47,7 +47,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -573,8 +573,6 @@ __ham_c_close(cursor)
DBC *cursor; DBC *cursor;
{ {
DB *ldbp; DB *ldbp;
HTAB *hashp;
HASH_CURSOR *hcp;
int ret; int ret;
DEBUG_LWRITE(cursor->dbp, cursor->txn, "ham_c_close", NULL, NULL, 0); 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) && if (F_ISSET(cursor->dbp, DB_AM_THREAD) &&
(ret = __db_gethandle(cursor->dbp, __ham_hdup, &ldbp)) != 0) (ret = __db_gethandle(cursor->dbp, __ham_hdup, &ldbp)) != 0)
return (ret); 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); ret = __ham_item_done(hashp, hcp, 0);
if (hcp->big_key) if (hcp->big_key)
@ -602,19 +624,16 @@ __ham_c_close(cursor)
/* /*
* All cursors (except the default ones) are linked off the master. * All cursors (except the default ones) are linked off the master.
* Therefore, when we close the cursor, we have to remove it from * 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 * the master, not the local one.
* its entirety, then we clear the THREAD bit and the master and * XXX I am always removing from the master; what about local cursors?
* local are identical, so we remove the correct one.
*/ */
DB_THREAD_LOCK(cursor->dbp); DB_THREAD_LOCK(dbc->dbp);
TAILQ_REMOVE(&cursor->dbp->curs_queue, cursor, links); TAILQ_REMOVE(&dbc->dbp->curs_queue, dbc, links);
DB_THREAD_UNLOCK(cursor->dbp); DB_THREAD_UNLOCK(dbc->dbp);
if (F_ISSET(cursor->dbp, DB_AM_THREAD))
__db_puthandle(ldbp);
FREE(hcp, sizeof(HASH_CURSOR)); FREE(hcp, sizeof(HASH_CURSOR));
FREE(cursor, sizeof(DBC)); FREE(dbc, sizeof(DBC));
return (ret); return (ret);
} }
@ -695,10 +714,9 @@ __ham_c_del(cursor, flags)
hcp->dndx = 0; /* Case 2 */ hcp->dndx = 0; /* Case 2 */
hcp->dpgno = PGNO(hcp->dpagep); hcp->dpgno = PGNO(hcp->dpagep);
if (ppgno == PGNO_INVALID) if (ppgno == PGNO_INVALID)
memcpy(P_ENTRY(hcp->pagep, memcpy(HOFFDUP_PGNO(P_ENTRY(hcp->pagep,
H_DATAINDEX(hcp->bndx)) + H_DATAINDEX(hcp->bndx))),
SSZ(HOFFDUP, pgno), &hcp->dpgno, &hcp->dpgno, sizeof(db_pgno_t));
sizeof(db_pgno_t));
F_SET(hcp, H_DELETED); F_SET(hcp, H_DELETED);
} else /* Case 1 */ } else /* Case 1 */
F_SET(hcp, H_DELETED); F_SET(hcp, H_DELETED);
@ -1051,18 +1069,17 @@ __ham_dup_return(hashp, hcp, val, flags)
DBT *val; DBT *val;
int flags; int flags;
{ {
HKEYDATA *hk;
PAGE *pp; PAGE *pp;
DBT *myval, tmp_val; DBT *myval, tmp_val;
db_indx_t ndx; db_indx_t ndx;
db_pgno_t pgno; db_pgno_t pgno;
u_int8_t type; u_int8_t *hk, type;
int indx, ret; int indx, ret;
db_indx_t len; db_indx_t len;
/* Check for duplicate and return the first one. */ /* Check for duplicate and return the first one. */
ndx = H_DATAINDEX(hcp->bndx); ndx = H_DATAINDEX(hcp->bndx);
type = GET_HKEYDATA(hcp->pagep, ndx)->type; type = HPAGE_TYPE(hcp->pagep, ndx);
pp = hcp->pagep; pp = hcp->pagep;
myval = val; myval = val;
@ -1088,7 +1105,8 @@ __ham_dup_return(hashp, hcp, val, flags)
hcp->dndx = 0; hcp->dndx = 0;
hcp->dup_off = 0; hcp->dup_off = 0;
do { do {
memcpy(&len, hk->data + hcp->dup_off, memcpy(&len,
HKEYDATA_DATA(hk) + hcp->dup_off,
sizeof(db_indx_t)); sizeof(db_indx_t));
hcp->dup_off += DUP_SIZE(len); hcp->dup_off += DUP_SIZE(len);
hcp->dndx++; hcp->dndx++;
@ -1096,15 +1114,15 @@ __ham_dup_return(hashp, hcp, val, flags)
hcp->dup_off -= DUP_SIZE(len); hcp->dup_off -= DUP_SIZE(len);
hcp->dndx--; hcp->dndx--;
} else { } else {
memcpy(&len, hk->data, sizeof(db_indx_t)); memcpy(&len,
HKEYDATA_DATA(hk), sizeof(db_indx_t));
hcp->dup_off = 0; hcp->dup_off = 0;
hcp->dndx = 0; hcp->dndx = 0;
} }
hcp->dup_len = len; hcp->dup_len = len;
} else if (type == H_OFFDUP) { } else if (type == H_OFFDUP) {
F_SET(hcp, H_ISDUP); F_SET(hcp, H_ISDUP);
memcpy(&pgno, memcpy(&pgno, HOFFDUP_PGNO(P_ENTRY(hcp->pagep, ndx)),
P_ENTRY(hcp->pagep, ndx) + SSZ(HOFFDUP, pgno),
sizeof(db_pgno_t)); sizeof(db_pgno_t));
if (flags == DB_LAST || flags == DB_PREV) { if (flags == DB_LAST || flags == DB_PREV) {
indx = (int)hcp->dndx; indx = (int)hcp->dndx;
@ -1166,7 +1184,7 @@ __ham_overwrite(hashp, hcp, nval)
DBT *nval; DBT *nval;
{ {
DBT *myval, tmp_val; DBT *myval, tmp_val;
HKEYDATA *hk; u_int8_t *hk;
if (F_ISSET(hashp->dbp, DB_AM_DUP)) if (F_ISSET(hashp->dbp, DB_AM_DUP))
return (__ham_add_dup(hashp, hcp, nval, DB_KEYLAST)); 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); F_SET(&tmp_val, DB_DBT_PARTIAL);
tmp_val.doff = 0; tmp_val.doff = 0;
hk = H_PAIRDATA(hcp->pagep, hcp->bndx); hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
if (hk->type == H_OFFPAGE) if (HPAGE_PTYPE(hk) == H_OFFPAGE)
memcpy(&tmp_val.dlen, memcpy(&tmp_val.dlen,
(u_int8_t *)hk + SSZ(HOFFPAGE, tlen), HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
sizeof(u_int32_t));
else else
tmp_val.dlen = LEN_HDATA(hcp->pagep, tmp_val.dlen = LEN_HDATA(hcp->pagep,
hashp->hdr->pagesize,hcp->bndx); hashp->hdr->pagesize,hcp->bndx);
@ -1207,10 +1224,10 @@ __ham_lookup(hashp, hcp, key, sought, mode)
u_int32_t sought; u_int32_t sought;
db_lockmode_t mode; db_lockmode_t mode;
{ {
HKEYDATA *hk;
db_pgno_t pgno; db_pgno_t pgno;
u_int32_t tlen; u_int32_t tlen;
int match, ret, t_ret; int match, ret, t_ret;
u_int8_t *hk;
/* /*
* Set up cursor so that we're looking for space to add an item * 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; break;
hk = H_PAIRKEY(hcp->pagep, hcp->bndx); hk = H_PAIRKEY(hcp->pagep, hcp->bndx);
switch (hk->type) { switch (HPAGE_PTYPE(hk)) {
case H_OFFPAGE: case H_OFFPAGE:
memcpy(&tlen, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen), memcpy(&tlen, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
sizeof(u_int32_t));
if (tlen == key->size) { if (tlen == key->size) {
memcpy(&pgno, memcpy(&pgno,
(u_int8_t *)hk + SSZ(HOFFPAGE, pgno), HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));
sizeof(db_pgno_t));
match = __db_moff(hashp->dbp, key, pgno); match = __db_moff(hashp->dbp, key, pgno);
if (match == 0) { if (match == 0) {
F_SET(hcp, H_OK); F_SET(hcp, H_OK);
@ -1247,7 +1262,8 @@ __ham_lookup(hashp, hcp, key, sought, mode)
case H_KEYDATA: case H_KEYDATA:
if (key->size == LEN_HKEY(hcp->pagep, if (key->size == LEN_HKEY(hcp->pagep,
hashp->hdr->pagesize, hcp->bndx) && 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); F_SET(hcp, H_OK);
return (0); return (0);
} }

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -20,12 +20,11 @@ static const char sccsid[] = "@(#)hash_conv.c 10.3 (Sleepycat) 6/21/97";
#include "hash.h" #include "hash.h"
/* /*
* __h_pgin, __ham_pgout -- * __ham_pgin --
* Convert host-specific page layout to/from the host-independent * Convert host-specific page layout from the host-independent format
* format stored on disk. * stored on disk.
* *
* PUBLIC: int __ham_pgin __P((db_pgno_t, void *, DBT *)); * PUBLIC: int __ham_pgin __P((db_pgno_t, void *, DBT *));
* PUBLIC: int __ham_pgout __P((db_pgno_t, void *, DBT *));
*/ */
int int
__ham_pgin(pg, pp, cookie) __ham_pgin(pg, pp, cookie)
@ -49,9 +48,17 @@ __ham_pgin(pg, pp, cookie)
if (!pginfo->needswap) if (!pginfo->needswap)
return (0); 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 int
__ham_pgout(pg, pp, cookie) __ham_pgout(pg, pp, cookie)
db_pgno_t pg; db_pgno_t pg;
@ -63,7 +70,8 @@ __ham_pgout(pg, pp, cookie)
pginfo = (DB_PGINFO *)cookie->data; pginfo = (DB_PGINFO *)cookie->data;
if (!pginfo->needswap) if (!pginfo->needswap)
return (0); 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));
} }
/* /*

View File

@ -42,7 +42,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
/* /*
@ -99,9 +99,9 @@ __ham_add_dup(hashp, hcp, nval, flags)
int flags; int flags;
{ {
DBT pval, tmp_val; DBT pval, tmp_val;
HKEYDATA *hk;
u_int32_t del_len, new_size; u_int32_t del_len, new_size;
int ret; int ret;
u_int8_t *hk;
if (flags == DB_CURRENT && hcp->dpgno == PGNO_INVALID) if (flags == DB_CURRENT && hcp->dpgno == PGNO_INVALID)
del_len = hcp->dup_len; 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 * 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 there isn't enough room on this page to add the next item.
*/ */
if (hk->type != H_OFFDUP && if (HPAGE_PTYPE(hk) != H_OFFDUP &&
(hk->type == H_OFFPAGE || ISBIG(hashp, new_size) || (HPAGE_PTYPE(hk) == H_OFFPAGE || ISBIG(hashp, new_size) ||
DUP_SIZE(nval->size) - del_len > P_FREESPACE(hcp->pagep))) { DUP_SIZE(nval->size) - del_len > P_FREESPACE(hcp->pagep))) {
if ((ret = __ham_dup_convert(hashp, hcp)) != 0) 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. */ /* There are two separate cases here: on page and off page. */
if (hk->type != H_OFFDUP) { if (HPAGE_PTYPE(hk) != H_OFFDUP) {
if (hk->type != H_DUPLICATE) { if (HPAGE_PTYPE(hk) != H_DUPLICATE) {
hk->type = H_DUPLICATE; HPAGE_PTYPE(hk) = H_DUPLICATE;
pval.flags = 0; pval.flags = 0;
pval.data = hk->data; pval.data = HKEYDATA_DATA(hk);
pval.size = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, pval.size = LEN_HDATA(hcp->pagep, hashp->hdr->pagesize,
hcp->bndx); hcp->bndx);
if ((ret = __ham_make_dup(&pval, &tmp_val, &hcp->big_data, if ((ret =
&hcp->big_datalen)) != 0 || __ham_make_dup(&pval, &tmp_val, &hcp->big_data,
(ret = __ham_replpair(hashp, hcp, &tmp_val, 1)) != 0) &hcp->big_datalen)) != 0 || (ret =
__ham_replpair(hashp, hcp, &tmp_val, 1)) != 0)
return (ret); return (ret);
} }
@ -187,8 +188,7 @@ __ham_add_dup(hashp, hcp, nval, flags)
/* If we get here, then we're on duplicate pages. */ /* If we get here, then we're on duplicate pages. */
if (hcp->dpgno == PGNO_INVALID) { if (hcp->dpgno == PGNO_INVALID) {
memcpy(&hcp->dpgno, memcpy(&hcp->dpgno, HOFFDUP_PGNO(hk), sizeof(db_pgno_t));
(u_int8_t *)hk + SSZ(HOFFDUP, pgno), sizeof(db_pgno_t));
hcp->dndx = 0; hcp->dndx = 0;
} }
@ -259,14 +259,13 @@ __ham_dup_convert(hashp, hcp)
* Now put the duplicates onto the new page. * Now put the duplicates onto the new page.
*/ */
dbt.flags = 0; dbt.flags = 0;
switch (((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->type) { switch (HPAGE_PTYPE(H_PAIRDATA(hcp->pagep, hcp->bndx))) {
case H_KEYDATA: case H_KEYDATA:
/* Simple case, one key on page; move it to dup page. */ /* Simple case, one key on page; move it to dup page. */
dndx = 0; dndx = 0;
dbt.size = dbt.size =
LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx); LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx);
dbt.data = dbt.data = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data;
ret = __db_pitem(hashp->dbp, hcp->dpagep, ret = __db_pitem(hashp->dbp, hcp->dpagep,
(u_int32_t)dndx, BKEYDATA_SIZE(dbt.size), NULL, &dbt); (u_int32_t)dndx, BKEYDATA_SIZE(dbt.size), NULL, &dbt);
if (ret == 0) if (ret == 0)
@ -289,7 +288,7 @@ __ham_dup_convert(hashp, hcp)
__ham_dirty_page(hashp, hcp->dpagep); __ham_dirty_page(hashp, hcp->dpagep);
break; break;
case H_DUPLICATE: case H_DUPLICATE:
p = ((HKEYDATA *)H_PAIRDATA(hcp->pagep, hcp->bndx))->data; p = HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
pend = p + pend = p +
LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx); LEN_HDATA(hcp->pagep, hashp->hdr->pagesize, hcp->bndx);
@ -366,24 +365,23 @@ __ham_check_move(hashp, hcp, add_len)
{ {
DBT k, d; DBT k, d;
DB_LSN new_lsn; DB_LSN new_lsn;
HKEYDATA *hk;
PAGE *next_pagep; PAGE *next_pagep;
db_pgno_t next_pgno; db_pgno_t next_pgno;
int rectype, ret; int rectype, ret;
u_int32_t new_datalen, old_len; 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, * 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. * then we'll have to move the current element to a new page.
*/ */
hk = H_PAIRDATA(hcp->pagep, hcp->bndx); hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
/* /*
* If the item is already off page duplicates or an offpage item, * 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 * 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); return (0);
old_len = old_len =
@ -443,22 +441,25 @@ __ham_check_move(hashp, hcp, add_len)
rectype = PUTPAIR; rectype = PUTPAIR;
k.flags = 0; k.flags = 0;
d.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; rectype |= PAIR_KEYMASK;
k.data = H_PAIRKEY(hcp->pagep, hcp->bndx); k.data = H_PAIRKEY(hcp->pagep, hcp->bndx);
k.size = HOFFPAGE_SIZE; k.size = HOFFPAGE_SIZE;
} else { } 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, k.size = LEN_HKEY(hcp->pagep,
hashp->hdr->pagesize, hcp->bndx); hashp->hdr->pagesize, hcp->bndx);
} }
if (hk->type == H_OFFPAGE) { if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
rectype |= PAIR_DATAMASK; rectype |= PAIR_DATAMASK;
d.data = H_PAIRDATA(hcp->pagep, hcp->bndx); d.data = H_PAIRDATA(hcp->pagep, hcp->bndx);
d.size = HOFFPAGE_SIZE; d.size = HOFFPAGE_SIZE;
} else { } 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, d.size = LEN_HDATA(hcp->pagep,
hashp->hdr->pagesize, hcp->bndx); hashp->hdr->pagesize, hcp->bndx);
} }

View File

@ -47,7 +47,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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)); * 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 u_int32_t
__ham_func2(key, len) __ham_func2(key, len)
@ -81,7 +81,7 @@ __ham_func2(key, len)
c = *k++; c = *k++;
if (!c && k > e) if (!c && k > e)
break; break;
dcharhash(h, c); DCHARHASH(h, c);
} }
return (h); return (h);
} }

View File

@ -47,10 +47,9 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
/* /*
* PACKAGE: hashing * 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)); static int __ham_lock_bucket __P((DB *, HASH_CURSOR *, db_lockmode_t));
#ifdef DEBUG_SLOW #ifdef DEBUG_SLOW
static void account_page(HTAB *, db_pgno_t, int); static void __account_page(HTAB *, db_pgno_t, int);
#endif #endif
/* /*
@ -121,7 +120,7 @@ __ham_item(hashp, cursorp, mode)
* pointer to be the beginning of the datum. * pointer to be the beginning of the datum.
*/ */
memcpy(&cursorp->dup_len, 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)); cursorp->dup_off, sizeof(db_indx_t));
else if (F_ISSET(cursorp, H_ISDUP)) { else if (F_ISSET(cursorp, H_ISDUP)) {
/* Make sure we're not about to run off the page. */ /* Make sure we're not about to run off the page. */
@ -326,8 +325,8 @@ __ham_item_prev(hashp, cursorp, mode)
else { else {
HASH_CURSOR *h; HASH_CURSOR *h;
h = cursorp; h = cursorp;
memcpy(&h->dup_len, memcpy(&h->dup_len, HKEYDATA_DATA(
H_PAIRDATA(h->pagep, h->bndx)->data H_PAIRDATA(h->pagep, h->bndx))
+ h->dup_off - sizeof(db_indx_t), + h->dup_off - sizeof(db_indx_t),
sizeof(db_indx_t)); sizeof(db_indx_t));
cursorp->dup_off -= cursorp->dup_off -=
@ -481,7 +480,7 @@ __ham_putitem(p, dbt, type)
} else { } else {
off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size); off = HOFFSET(p) - HKEYDATA_SIZE(dbt->size);
HOFFSET(p) = p->inp[n] = off; 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. */ /* Adjust page info. */
@ -524,24 +523,24 @@ __ham_del_pair(hashp, cursorp)
* entry referring to the big item. * entry referring to the big item.
*/ */
ret = 0; ret = 0;
if (H_PAIRKEY(p, ndx)->type == H_OFFPAGE) { if (HPAGE_PTYPE(H_PAIRKEY(p, ndx)) == H_OFFPAGE) {
memcpy(&pgno, (u_int8_t *)GET_HOFFPAGE(p, H_KEYINDEX(ndx)) + memcpy(&pgno, HOFFPAGE_PGNO(P_ENTRY(p, H_KEYINDEX(ndx))),
SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t)); sizeof(db_pgno_t));
ret = __db_doff(hashp->dbp, pgno, __ham_del_page); ret = __db_doff(hashp->dbp, pgno, __ham_del_page);
} }
if (ret == 0) if (ret == 0)
switch (H_PAIRDATA(p, ndx)->type) { switch (HPAGE_PTYPE(H_PAIRDATA(p, ndx))) {
case H_OFFPAGE: case H_OFFPAGE:
memcpy(&pgno, memcpy(&pgno,
(u_int8_t *)GET_HOFFPAGE(p, H_DATAINDEX(ndx)) + HOFFPAGE_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
SSZ(HOFFPAGE, pgno), sizeof(db_pgno_t)); sizeof(db_pgno_t));
ret = __db_doff(hashp->dbp, pgno, __ham_del_page); ret = __db_doff(hashp->dbp, pgno, __ham_del_page);
break; break;
case H_OFFDUP: case H_OFFDUP:
memcpy(&pgno, memcpy(&pgno,
(u_int8_t *)GET_HOFFDUP(p, H_DATAINDEX(ndx)) + HOFFDUP_PGNO(P_ENTRY(p, H_DATAINDEX(ndx))),
SSZ(HOFFDUP, pgno), sizeof(db_pgno_t)); sizeof(db_pgno_t));
ret = __db_ddup(hashp->dbp, pgno, __ham_del_page); ret = __db_ddup(hashp->dbp, pgno, __ham_del_page);
break; break;
} }
@ -706,13 +705,12 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
DBT *dbt; DBT *dbt;
u_int32_t make_dup; u_int32_t make_dup;
{ {
DBT old_dbt, tmp; DBT old_dbt, tdata, tmp;
DB_LSN new_lsn; DB_LSN new_lsn;
HKEYDATA *hk;
u_int32_t len; u_int32_t len;
int32_t change; int32_t change;
int is_big, ret, type; 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. * Big item replacements are handled in generic code.
@ -738,11 +736,10 @@ __ham_replpair(hashp, hcp, dbt, make_dup)
change = dbt->size - dbt->dlen; change = dbt->size - dbt->dlen;
hk = H_PAIRDATA(hcp->pagep, hcp->bndx); hk = H_PAIRDATA(hcp->pagep, hcp->bndx);
is_big = hk->type == H_OFFPAGE; is_big = HPAGE_PTYPE(hk) == H_OFFPAGE;
if (is_big) if (is_big)
memcpy(&len, (u_int8_t *)hk + SSZ(HOFFPAGE, tlen), memcpy(&len, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));
sizeof(u_int32_t));
else else
len = LEN_HKEYDATA(hcp->pagep, len = LEN_HKEYDATA(hcp->pagep,
hashp->dbp->pgsize, H_DATAINDEX(hcp->bndx)); 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) &tmp, &hcp->big_key, &hcp->big_keylen)) != 0)
return (ret); return (ret);
type = hk->type;
if (dbt->doff == 0 && dbt->dlen == len) { if (dbt->doff == 0 && dbt->dlen == len) {
ret = __ham_del_pair(hashp, hcp); ret = __ham_del_pair(hashp, hcp);
if (ret == 0) 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 */ } else { /* Case B */
DBT tdata; type = HPAGE_PTYPE(hk) != H_OFFPAGE ?
HPAGE_PTYPE(hk) : H_KEYDATA;
tdata.flags = 0; tdata.flags = 0;
F_SET(&tdata, DB_DBT_MALLOC | DB_DBT_INTERNAL); 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 * Set up pointer into existing data. Do it before the log
* message so we can use it inside of the log setup. * 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; beg += dbt->doff;
/* /*
@ -885,11 +883,11 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt)
if (off < 0) if (off < 0)
len = pagep->inp[ndx] - HOFFSET(pagep); len = pagep->inp[ndx] - HOFFSET(pagep);
else if ((u_int32_t)off >= LEN_HKEYDATA(pagep, pgsize, ndx)) { 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; LEN_HKEYDATA(pagep, pgsize, ndx) - src;
zero_me = 1; zero_me = 1;
} else } else
len = (GET_HKEYDATA(pagep, ndx)->data + off) - src; len = (HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off) - src;
dest = src - change; dest = src - change;
memmove(dest, src, len); memmove(dest, src, len);
if (zero_me) if (zero_me)
@ -901,7 +899,7 @@ __ham_onpage_replace(pagep, pgsize, ndx, off, change, dbt)
HOFFSET(pagep) -= change; HOFFSET(pagep) -= change;
} }
if (off >= 0) if (off >= 0)
memcpy(GET_HKEYDATA(pagep, ndx)->data + off, memcpy(HKEYDATA_DATA(P_ENTRY(pagep, ndx)) + off,
dbt->data, dbt->size); dbt->data, dbt->size);
else else
memcpy(P_ENTRY(pagep, ndx), dbt->data, dbt->size); memcpy(P_ENTRY(pagep, ndx), dbt->data, dbt->size);
@ -1319,7 +1317,7 @@ __ham_new_page(hashp, addr, type, pp)
return (ret); return (ret);
#ifdef DEBUG_SLOW #ifdef DEBUG_SLOW
account_page(hashp, addr, 1); __account_page(hashp, addr, 1);
#endif #endif
/* This should not be necessary because page-in should do it. */ /* This should not be necessary because page-in should do it. */
P_INIT(pagep, P_INIT(pagep,
@ -1398,7 +1396,7 @@ __ham_put_page(dbp, pagep, is_dirty)
int32_t is_dirty; int32_t is_dirty;
{ {
#ifdef DEBUG_SLOW #ifdef DEBUG_SLOW
account_page((HTAB *)dbp->cookie, __account_page((HTAB *)dbp->cookie,
((BKT *)((char *)pagep - sizeof(BKT)))->pgno, -1); ((BKT *)((char *)pagep - sizeof(BKT)))->pgno, -1);
#endif #endif
return (memp_fput(dbp->mpf, pagep, (is_dirty ? DB_MPOOL_DIRTY : 0))); 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); ret = memp_fget(dbp->mpf, &addr, DB_MPOOL_CREATE, pagep);
#ifdef DEBUG_SLOW #ifdef DEBUG_SLOW
if (*pagep != NULL) if (*pagep != NULL)
account_page((HTAB *)dbp->internal, addr, 1); __account_page((HTAB *)dbp->internal, addr, 1);
#endif #endif
return (ret); return (ret);
} }
@ -1523,11 +1521,11 @@ __ham_overflow_page(dbp, type, pp)
#ifdef DEBUG #ifdef DEBUG
/* /*
* PUBLIC: #ifdef DEBUG * PUBLIC: #ifdef DEBUG
* PUBLIC: int bucket_to_page __P((HTAB *, int)); * PUBLIC: int __bucket_to_page __P((HTAB *, int));
* PUBLIC: #endif * PUBLIC: #endif
*/ */
int int
bucket_to_page(hashp, n) __bucket_to_page(hashp, n)
HTAB *hashp; HTAB *hashp;
int n; int n;
{ {
@ -1735,7 +1733,7 @@ __ham_dpair(dbp, p, pndx)
#ifdef DEBUG_SLOW #ifdef DEBUG_SLOW
static void static void
account_page(hashp, pgno, inout) __account_page(hashp, pgno, inout)
HTAB *hashp; HTAB *hashp;
db_pgno_t pgno; db_pgno_t pgno;
int inout; int inout;
@ -1767,7 +1765,8 @@ account_page(hashp, pgno, inout)
last--; last--;
} }
for (i = 0; i < last; i++, list[i].times++) 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, (void)fprintf(stderr,
"Warning: pg %lu has been out for %d times\n", "Warning: pg %lu has been out for %d times\n",
(u_long)list[i].pgno, list[i].times); (u_long)list[i].pgno, list[i].times);

View File

@ -47,7 +47,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -364,11 +364,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info)
DB *mdbp, *file_dbp; DB *mdbp, *file_dbp;
DB_MPOOLFILE *mpf; DB_MPOOLFILE *mpf;
DBT dbt; DBT dbt;
HKEYDATA *hk;
HTAB *hashp; HTAB *hashp;
PAGE *pagep; PAGE *pagep;
int32_t grow; int32_t grow;
int change, cmp_n, cmp_p, getmeta, ret; int change, cmp_n, cmp_p, getmeta, ret;
u_int8_t *hk;
getmeta = 0; getmeta = 0;
hashp = NULL; /* XXX: shut the compiler up. */ hashp = NULL; /* XXX: shut the compiler up. */
@ -421,11 +421,11 @@ __ham_replace_recover(logp, dbtp, lsnp, redo, info)
__ham_onpage_replace(pagep, __ham_onpage_replace(pagep,
file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt); file_dbp->pgsize, argp->ndx, argp->off, grow, &dbt);
if (argp->makedup) { if (argp->makedup) {
hk = GET_HKEYDATA(pagep, argp->ndx); hk = P_ENTRY(pagep, argp->ndx);
if (redo) if (redo)
hk->type = H_DUPLICATE; HPAGE_PTYPE(hk) = H_DUPLICATE;
else else
hk->type = H_KEYDATA; HPAGE_PTYPE(hk) = H_KEYDATA;
} }
} }

View File

@ -43,7 +43,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)btree.h 10.16 (Sleepycat) 8/24/97 * @(#)btree.h 10.17 (Sleepycat) 9/23/97
*/ */
/* Forward structure declarations. */ /* Forward structure declarations. */
@ -181,6 +181,12 @@ struct __cursor {
#define C_DELETED 0x0001 #define C_DELETED 0x0001
#define C_REPLACE 0x0002 #define C_REPLACE 0x0002
#define C_REPLACE_SETUP 0x0004 #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; u_int32_t flags;
}; };

View File

@ -8,6 +8,7 @@ int __bam_pgin __P((db_pgno_t, void *, DBT *));
int __bam_pgout __P((db_pgno_t, void *, DBT *)); int __bam_pgout __P((db_pgno_t, void *, DBT *));
int __bam_mswap __P((PAGE *)); int __bam_mswap __P((PAGE *));
int __bam_cursor __P((DB *, DB_TXN *, DBC **)); 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_get __P((DB *, DB_TXN *, DBT *, DBT *, int));
int __bam_ovfl_chk __P((DB *, CURSOR *, u_int32_t, 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 *)); 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_open __P((DB *, DBTYPE, DB_INFO *));
int __ram_cursor __P((DB *, DB_TXN *, DBC **)); int __ram_cursor __P((DB *, DB_TXN *, DBC **));
int __ram_close __P((DB *)); int __ram_close __P((DB *));
int __ram_c_iclose __P((DB *, DBC *));
void __ram_ca __P((DB *, db_recno_t, ca_recno_arg)); void __ram_ca __P((DB *, db_recno_t, ca_recno_arg));
int __ram_getno __P((DB *, const DBT *, db_recno_t *, int)); int __ram_getno __P((DB *, const DBT *, db_recno_t *, int));
int __ram_snapshot __P((DB *)); int __ram_snapshot __P((DB *));

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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_ #ifndef _DB_H_
@ -67,8 +67,8 @@
#define DB_VERSION_MAJOR 2 #define DB_VERSION_MAJOR 2
#define DB_VERSION_MINOR 3 #define DB_VERSION_MINOR 3
#define DB_VERSION_PATCH 4 #define DB_VERSION_PATCH 10
#define DB_VERSION_STRING "Sleepycat Software: DB 2.3.4: (8/20/97)" #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_int32_t db_pgno_t; /* Page number type. */
typedef u_int16_t db_indx_t; /* Page offset 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_NEEDSPLIT ( -9) /* Page needs to be split. */
#define DB_REGISTERED (-10) /* Entry was previously registered. */ #define DB_REGISTERED (-10) /* Entry was previously registered. */
#define DB_SWAPBYTES (-11) /* Database needs byte swapping. */ #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. */ struct __db_ilock { /* Internal DB access method lock. */
db_pgno_t pgno; /* Page being locked. */ db_pgno_t pgno; /* Page being locked. */
@ -338,7 +339,7 @@ struct __db_ilock { /* Internal DB access method lock. */
/* DB access method description structure. */ /* DB access method description structure. */
struct __db { struct __db {
void *mutex; /* Synchronization for free threading */ void *mutexp; /* Synchronization for free threading */
DBTYPE type; /* DB access method. */ DBTYPE type; /* DB access method. */
DB_ENV *dbenv; /* DB_ENV structure. */ DB_ENV *dbenv; /* DB_ENV structure. */
DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */ DB_ENV *mp_dbenv; /* DB_ENV for local mpool creation. */
@ -640,11 +641,11 @@ extern "C" {
#endif #endif
int memp_close __P((DB_MPOOL *)); int memp_close __P((DB_MPOOL *));
int memp_fclose __P((DB_MPOOLFILE *)); 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 memp_fopen __P((DB_MPOOL *, const char *,
int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **)); int, int, int, size_t, int, DBT *, u_int8_t *, DB_MPOOLFILE **));
int memp_fput __P((DB_MPOOLFILE *, void *, unsigned long)); int memp_fput __P((DB_MPOOLFILE *, void *, int));
int memp_fset __P((DB_MPOOLFILE *, void *, unsigned long)); int memp_fset __P((DB_MPOOLFILE *, void *, int));
int memp_fsync __P((DB_MPOOLFILE *)); int memp_fsync __P((DB_MPOOLFILE *));
int memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **)); int memp_open __P((const char *, int, int, DB_ENV *, DB_MPOOL **));
int memp_register __P((DB_MPOOL *, int, int memp_register __P((DB_MPOOL *, int,
@ -697,7 +698,7 @@ extern "C" {
#endif #endif
int txn_abort __P((DB_TXN *)); int txn_abort __P((DB_TXN *));
int txn_begin __P((DB_TXNMGR *, DB_TXN *, 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_commit __P((DB_TXN *));
int txn_close __P((DB_TXNMGR *)); int txn_close __P((DB_TXNMGR *));
u_int32_t txn_id __P((DB_TXN *)); u_int32_t txn_id __P((DB_TXN *));

View File

@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * 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_ #ifndef _DB_185_H_
@ -72,6 +72,14 @@
@u_int32_decl@ @u_int32_decl@
#endif #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 */ #define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
typedef u_int32_t pgno_t; typedef u_int32_t pgno_t;
#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */ #define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */

View File

@ -4,7 +4,7 @@
* Copyright (c) 1997 * Copyright (c) 1997
* Sleepycat Software. All rights reserved. * 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_ #ifndef _DB_CXX_H_
@ -303,9 +303,9 @@ class _exported DbMpoolFile
{ {
public: public:
int close(); int close();
int get(db_pgno_t *pgnoaddr, unsigned long flags, void *pagep); int get(db_pgno_t *pgnoaddr, int flags, void *pagep);
int put(void *pgaddr, unsigned long flags); int put(void *pgaddr, int flags);
int set(void *pgaddr, unsigned long flags); int set(void *pgaddr, int flags);
int sync(); int sync();
static int open(DbMpool *mp, const char *file, static int open(DbMpool *mp, const char *file,
@ -391,7 +391,7 @@ class _exported DbTxnMgr
friend DbEnv; friend DbEnv;
public: public:
int begin(DbTxn *pid, DbTxn **tid); int begin(DbTxn *pid, DbTxn **tid);
int checkpoint(long kbyte, long min) const; int checkpoint(int kbyte, int min) const;
int close(); int close();
int stat(DB_TXN_STAT **statp, void *(*db_malloc)(size_t)); int stat(DB_TXN_STAT **statp, void *(*db_malloc)(size_t));

View File

@ -57,8 +57,8 @@ int __db_noop_print
int __db_noop_read __P((void *, __db_noop_args **)); int __db_noop_read __P((void *, __db_noop_args **));
int __db_init_print __P((DB_ENV *)); int __db_init_print __P((DB_ENV *));
int __db_init_recover __P((DB_ENV *)); int __db_init_recover __P((DB_ENV *));
int __db_pgin __P((db_pgno_t, void *)); int __db_pgin __P((db_pgno_t, size_t, void *));
int __db_pgout __P((db_pgno_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_dispatch __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
int __db_add_recovery __P((DB_ENV *, int __db_add_recovery __P((DB_ENV *,
int (*)(DB_LOG *, DBT *, DB_LSN *, int, void *), u_int32_t)); int (*)(DB_LOG *, DBT *, DB_LSN *, int, void *), u_int32_t));

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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_ #ifndef _DB_INTERNAL_H_
@ -177,11 +177,11 @@ typedef struct _db_mutex_t {
/* Lock/unlock a DB thread. */ /* Lock/unlock a DB thread. */
#define DB_THREAD_LOCK(dbp) \ #define DB_THREAD_LOCK(dbp) \
(F_ISSET(dbp, DB_AM_THREAD) ? \ (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) (dbp)->dbenv == NULL ? NULL : (dbp)->dbenv->db_yield) : 0)
#define DB_THREAD_UNLOCK(dbp) \ #define DB_THREAD_UNLOCK(dbp) \
(F_ISSET(dbp, DB_AM_THREAD) ? \ (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. */ /* Btree/recno local statistics structure. */
struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT; struct __db_bt_lstat; typedef struct __db_bt_lstat DB_BTREE_LSTAT;
@ -305,14 +305,6 @@ typedef struct __dbpginfo {
/******************************************************* /*******************************************************
* Transactions and recovery. * 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 * 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 * into the lock regions. Since the RLAYOUT structure begins all regions, an

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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_ #ifndef _DB_PAGE_H_
@ -272,6 +272,17 @@ typedef struct _db_page {
#define H_OFFPAGE 3 /* Overflow key/data item. */ #define H_OFFPAGE 3 /* Overflow key/data item. */
#define H_OFFDUP 4 /* Overflow page of duplicates. */ #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 * The first and second types are H_KEYDATA and H_DUPLICATE, represented
* by the HKEYDATA structure: * by the HKEYDATA structure:
@ -294,10 +305,7 @@ typedef struct _hkeydata {
u_int8_t type; /* 00: Page type. */ u_int8_t type; /* 00: Page type. */
u_int8_t data[1]; /* Variable length key/data item. */ u_int8_t data[1]; /* Variable length key/data item. */
} HKEYDATA; } HKEYDATA;
#define HKEYDATA_DATA(p) (((u_int8_t *)p) + SSZA(HKEYDATA, data))
/* Get a HKEYDATA item for a specific index. */
#define GET_HKEYDATA(pg, indx) \
((HKEYDATA *)P_ENTRY(pg, indx))
/* /*
* The length of any HKEYDATA item. Note that indx is an element index, * 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_NUMPAIRS(pg) (NUM_ENT(pg) / 2)
#define H_KEYINDEX(pindx) (2 * (pindx)) #define H_KEYINDEX(pindx) (2 * (pindx))
#define H_DATAINDEX(pindx) ((2 * (pindx)) + 1) #define H_DATAINDEX(pindx) ((2 * (pindx)) + 1)
#define H_PAIRKEY(pg, pindx) GET_HKEYDATA(pg, H_KEYINDEX(pindx)) #define H_PAIRKEY(pg, pindx) P_ENTRY(pg, H_KEYINDEX(pindx))
#define H_PAIRDATA(pg, pindx) GET_HKEYDATA(pg, H_DATAINDEX(pindx)) #define H_PAIRDATA(pg, pindx) P_ENTRY(pg, H_DATAINDEX(pindx))
#define H_PAIRSIZE(pg, psize, pindx) \ #define H_PAIRSIZE(pg, psize, pindx) \
(LEN_HITEM(pg, psize, H_KEYINDEX(pindx)) + \ (LEN_HITEM(pg, psize, H_KEYINDEX(pindx)) + \
LEN_HITEM(pg, psize, H_DATAINDEX(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. */ u_int32_t tlen; /* 08-11: Total length of item. */
} HOFFPAGE; } HOFFPAGE;
/* Get a HOFFPAGE item for a specific index. */ #define HOFFPAGE_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, pgno))
#define GET_HOFFPAGE(pg, indx) \ #define HOFFPAGE_TLEN(p) (((u_int8_t *)p) + SSZ(HOFFPAGE, tlen))
((HOFFPAGE *)P_ENTRY(pg, indx))
/* /*
* Page space required to add a new HOFFPAGE item to the page, with and * 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. */ u_int8_t unused[3]; /* 01-03: Padding, unused. */
db_pgno_t pgno; /* 04-07: Offpage page number. */ db_pgno_t pgno; /* 04-07: Offpage page number. */
} HOFFDUP; } HOFFDUP;
#define HOFFDUP_PGNO(p) (((u_int8_t *)p) + SSZ(HOFFDUP, pgno))
/* Get a HOFFDUP item for a specific index. */
#define GET_HOFFDUP(pg, indx) \
((HOFFDUP *)P_ENTRY(pg, indx))
/* /*
* Page space required to add a new HOFFDUP item to the page, with and * Page space required to add a new HOFFDUP item to the page, with and

View File

@ -4,14 +4,14 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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 */ /* Hash Headers */
typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB; typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
/* /*
* __db_hashlookup -- * HASHLOOKUP --
* *
* Look up something in a shared memory hash table. The "elt" argument * 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 * 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 * If the element is not in the hash table, this macro exits with result
* set to NULL. * 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; \ DB_HASHTAB *__bucket; \
u_int32_t __ndx; \ u_int32_t __ndx; \
\ \
@ -43,10 +43,10 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
} while(0) } while(0)
/* /*
* __db_hashinsert -- * HASHINSERT --
* *
* Insert a new entry into the hash table. This assumes that lookup has * 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. * begin: the beginning address of the hash table.
* type: the structure type of the elements that are linked in each bucket. * 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. * 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. * nelems: the number of buckets in the hash table.
* hash_func: the hash function that operates on elements of the type of elt * 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; \ u_int32_t __ndx; \
DB_HASHTAB *__bucket; \ DB_HASHTAB *__bucket; \
\ \
@ -64,7 +64,7 @@ typedef SH_TAILQ_HEAD(hash_head) DB_HASHTAB;
} while(0) } while(0)
/* /*
* __db_hashremove -- * HASHREMOVE --
* Remove the entry with a key == elt. * Remove the entry with a key == elt.
* begin: address of the beginning of the hash table. * begin: address of the beginning of the hash table.
* type: the structure type of the elements that are linked in each bucket. * 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 * cmp_func: compare elements of the type of elt with those in the table (of
* type "type"). * 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; \ u_int32_t __ndx; \
DB_HASHTAB *__bucket; \ DB_HASHTAB *__bucket; \
SH_TAILQ_ENTRY *__entp; \ SH_TAILQ_ENTRY *__entp; \
\ \
__ndx = hash(elt) % (n); \ __ndx = hash(elt) % (n); \
__bucket = &begin[__ndx]; \ __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); \ SH_TAILQ_REMOVE(__bucket, __entp, field, type); \
} }
/* /*
* __db_hashremove_el -- * HASHREMOVE_EL --
* Given the object "obj" in the table, remove it. * Given the object "obj" in the table, remove it.
* begin: address of the beginning of the hash table. * begin: address of the beginning of the hash table.
* type: the structure type of the elements that are linked in each bucket. * 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. * nelems: the number of buckets in the hash table.
* hash_func: the hash function that operates on elements of the type of elt * 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; \ u_int32_t __ndx; \
DB_HASHTAB *__bucket; \ DB_HASHTAB *__bucket; \
\ \

View File

@ -1,6 +1,7 @@
/* Do not edit: automatically built by dist/distrib. */ /* Do not edit: automatically built by dist/distrib. */
int __ham_open __P((DB *, DB_INFO *)); int __ham_open __P((DB *, DB_INFO *));
int __ham_close __P((DB *)); int __ham_close __P((DB *));
int __ham_c_iclose __P((DB *, DBC *));
int __ham_expand_table __P((HTAB *)); int __ham_expand_table __P((HTAB *));
u_int32_t __ham_call_hash __P((HTAB *, u_int8_t *, int32_t)); 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 *)); 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_get_page __P((DB *, db_pgno_t, PAGE **));
int __ham_overflow_page __P((DB *, u_int32_t, PAGE **)); int __ham_overflow_page __P((DB *, u_int32_t, PAGE **));
#ifdef DEBUG #ifdef DEBUG
int bucket_to_page __P((HTAB *, int)); int __bucket_to_page __P((HTAB *, int));
#endif #endif
void __ham_init_ovflpages __P((HTAB *)); void __ham_init_ovflpages __P((HTAB *));
int __ham_get_cpage __P((HTAB *, HASH_CURSOR *, db_lockmode_t)); int __ham_get_cpage __P((HTAB *, HASH_CURSOR *, db_lockmode_t));

View File

@ -4,13 +4,19 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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; typedef struct __db_lockobj DB_LOCKOBJ;
#define DB_DEFAULT_LOCK_FILE "__db_lock.share" #define DB_DEFAULT_LOCK_FILE "__db_lock.share"
#define DB_LOCK_DEFAULT_N 5000 #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 #define DB_LOCK_MAXID 0x7fffffff
/* /*

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
* *
* @(#)log.h 10.8 (Sleepycat) 8/18/97 * @(#)log.h 10.9 (Sleepycat) 9/23/97
*/ */
#ifndef _LOG_H_ #ifndef _LOG_H_
@ -30,11 +30,11 @@ struct __log_persist; typedef struct __log_persist LOGP;
/* Macros to lock/unlock the region and threads. */ /* Macros to lock/unlock the region and threads. */
#define LOCK_LOGTHREAD(dblp) \ #define LOCK_LOGTHREAD(dblp) \
if (F_ISSET(dblp, DB_AM_THREAD)) \ 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) (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
#define UNLOCK_LOGTHREAD(dblp) \ #define UNLOCK_LOGTHREAD(dblp) \
if (F_ISSET(dblp, DB_AM_THREAD)) \ 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) \ #define LOCK_LOGREGION(dblp) \
(void)__db_mutex_lock(&((RLAYOUT *)(dblp)->lp)->lock, \ (void)__db_mutex_lock(&((RLAYOUT *)(dblp)->lp)->lock, \
(dblp)->fd, (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield) (dblp)->fd, (dblp)->dbenv == NULL ? NULL : (dblp)->dbenv->db_yield)
@ -56,7 +56,7 @@ typedef struct __db_entry {
*/ */
struct __db_log { struct __db_log {
/* These fields need to be protected for multi-threaded support. */ /* 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. */ DB_ENTRY *dbentry; /* Recovery file-id mapping. */
#define DB_GROW_SIZE 64 #define DB_GROW_SIZE 64
@ -86,6 +86,8 @@ struct __db_log {
void *addr; /* Address of shalloc() region. */ void *addr; /* Address of shalloc() region. */
int fd; /* Region file descriptor. */ int fd; /* Region file descriptor. */
char *dir; /* Directory argument. */
u_int32_t flags; /* Support the DB_AM_XXX flags. */ u_int32_t flags; /* Support the DB_AM_XXX flags. */
}; };

View File

@ -1,6 +1,6 @@
/* Do not edit: automatically built by dist/distrib. */ /* Do not edit: automatically built by dist/distrib. */
int __log_find __P((DB_ENV *, LOG *, int *)); int __log_find __P((DB_LOG *, int *));
int __log_valid __P((DB_ENV *, LOG *, int)); int __log_valid __P((DB_LOG *, LOG *, int));
int __log_register_log int __log_register_log
__P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t, __P((DB_LOG *, DB_TXN *, DB_LSN *, u_int32_t,
DBT *, DBT *, u_int32_t, DBTYPE)); 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_findckp __P((DB_LOG *, DB_LSN *));
int __log_get __P((DB_LOG *, DB_LSN *, DBT *, int, int)); int __log_get __P((DB_LOG *, DB_LSN *, DBT *, int, int));
int __log_put __P((DB_LOG *, DB_LSN *, const DBT *, 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 int __log_register_recover
__P((DB_LOG *, DBT *, DB_LSN *, int, void *)); __P((DB_LOG *, DBT *, DB_LSN *, int, void *));
int __log_unregister_recover int __log_unregister_recover

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * 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; struct __bh; typedef struct __bh BH;
@ -99,7 +99,7 @@ struct __mpoolfile; typedef struct __mpoolfile MPOOLFILE;
*/ */
struct __db_mpool { struct __db_mpool {
/* These fields need to be protected for multi-threaded support. */ /* 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 of pgin/pgout routines. */
LIST_HEAD(__db_mpregh, __db_mpreg) dbregq; LIST_HEAD(__db_mpregh, __db_mpreg) dbregq;
@ -145,7 +145,7 @@ struct __db_mpreg {
*/ */
struct __db_mpoolfile { struct __db_mpoolfile {
/* These fields need to be protected for multi-threaded support. */ /* 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. */ int fd; /* Underlying file descriptor. */

View File

@ -1,38 +1,11 @@
/* /*-
* Copyright (c) 1991, 1993 * See the file LICENSE for redistribution information.
* The Regents of the University of California. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Copyright (c) 1996, 1997
* modification, are permitted provided that the following conditions * Sleepycat Software. All rights reserved.
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * @(#)shqueue.h 8.12 (Sleepycat) 9/10/97
* ANY EXPRESS OR 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.
*
* @(#)shqueue.h 8.11 (Sleepycat) 7/27/97
*/ */
#ifndef _SYS_SHQUEUE_H_ #ifndef _SYS_SHQUEUE_H_
#define _SYS_SHQUEUE_H_ #define _SYS_SHQUEUE_H_

View File

@ -4,7 +4,7 @@
* Copyright (c) 1996, 1997 * Copyright (c) 1996, 1997
* Sleepycat Software. All rights reserved. * Sleepycat Software. All rights reserved.
* *
* @(#)txn.h 10.6 (Sleepycat) 7/29/97 * @(#)txn.h 10.10 (Sleepycat) 9/23/97
*/ */
#ifndef _TXN_H_ #ifndef _TXN_H_
#define _TXN_H_ #define _TXN_H_
@ -14,8 +14,9 @@
* the region is always created group RW of the group owning the directory. * the region is always created group RW of the group owning the directory.
*/ */
#define DEFAULT_TXN_FILE "__db_txn.share" #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_INVALID 0xffffffff /* Maximum number of txn ids. */
#define TXN_MINIMUM 0x80000000 /* First transaction id */
/* /*
* Transaction type declarations. * Transaction type declarations.
@ -36,6 +37,7 @@ typedef struct __txn_detail {
#define TXN_ABORTED 2 #define TXN_ABORTED 2
#define TXN_PREPARED 3 #define TXN_PREPARED 3
u_int32_t status; /* status of the transaction */ u_int32_t status; /* status of the transaction */
SH_TAILQ_ENTRY links; /* free/active list */
} TXN_DETAIL; } TXN_DETAIL;
/* /*
@ -45,7 +47,7 @@ typedef struct __txn_detail {
*/ */
struct __db_txnmgr { struct __db_txnmgr {
/* These fields need to be protected for multi-threaded support. */ /* These fields need to be protected for multi-threaded support. */
db_mutex_t mutex; /* Synchronization. */ db_mutex_t *mutexp; /* Synchronization. */
/* list of active transactions */ /* list of active transactions */
TAILQ_HEAD(_chain, __db_txn) txn_chain; TAILQ_HEAD(_chain, __db_txn) txn_chain;
@ -57,11 +59,14 @@ struct __db_txnmgr {
u_int flags; /* DB_TXN_NOSYNC, DB_THREAD */ u_int flags; /* DB_TXN_NOSYNC, DB_THREAD */
size_t reg_size; /* how large we think the region is */ size_t reg_size; /* how large we think the region is */
DB_TXNREGION *region; /* address of shared memory region */ DB_TXNREGION *region; /* address of shared memory region */
void *mem; /* address of the shalloc space */
}; };
/* /*
* Layout of the shared memory region. * 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 { struct __db_txnregion {
RLAYOUT hdr; /* Shared memory region header. */ RLAYOUT hdr; /* Shared memory region header. */
@ -69,7 +74,6 @@ struct __db_txnregion {
u_int32_t version; /* version number */ u_int32_t version; /* version number */
u_int32_t maxtxns; /* maximum number of active txns */ u_int32_t maxtxns; /* maximum number of active txns */
u_int32_t last_txnid; /* last transaction id given out */ 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 pending_ckp; /* last checkpoint did not finish */
DB_LSN last_ckp; /* lsn of the last checkpoint */ DB_LSN last_ckp; /* lsn of the last checkpoint */
time_t time_ckp; /* time of 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 naborts; /* number of aborted transactions */
u_int32_t ncommits; /* number of committed transactions */ u_int32_t ncommits; /* number of committed transactions */
u_int32_t nbegins; /* number of begun 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) \ #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. */ /* Macros to lock/unlock the region and threads. */
#define LOCK_TXNTHREAD(tmgrp) \ #define LOCK_TXNTHREAD(tmgrp) \
if (F_ISSET(tmgrp, DB_THREAD)) \ 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) (tmgrp)->dbenv == NULL ? NULL : (tmgrp)->dbenv->db_yield)
#define UNLOCK_TXNTHREAD(tmgrp) \ #define UNLOCK_TXNTHREAD(tmgrp) \
if (F_ISSET(tmgrp, DB_THREAD)) \ if (F_ISSET(tmgrp, DB_THREAD)) \
(void)__db_mutex_unlock(&(tmgrp)->mutex, -1) (void)__db_mutex_unlock((tmgrp)->mutexp, -1)
#define LOCK_TXNREGION(tmgrp) \ #define LOCK_TXNREGION(tmgrp) \
(void)__db_mutex_lock(&(tmgrp)->region->hdr.lock,(tmgrp)->fd, \ (void)__db_mutex_lock(&(tmgrp)->region->hdr.lock,(tmgrp)->fd, \

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -201,7 +201,7 @@ lock_open(path, flags, mode, dbenv, ltp)
* Create the lock table structure. * Create the lock table structure.
*/ */
if ((lt = (DB_LOCKTAB *)calloc(1, sizeof(DB_LOCKTAB))) == NULL) { if ((lt = (DB_LOCKTAB *)calloc(1, sizeof(DB_LOCKTAB))) == NULL) {
__db_err(dbenv, "%s", strerror(errno)); __db_err(dbenv, "%s", strerror(ENOMEM));
return (ENOMEM); return (ENOMEM);
} }
lt->dbenv = dbenv; lt->dbenv = dbenv;
@ -319,8 +319,10 @@ lock_vec(lt, locker, flags, list, nlist, elistp)
case DB_LOCK_GET: case DB_LOCK_GET:
ret = __lock_get_internal(lt, locker, flags, ret = __lock_get_internal(lt, locker, flags,
list[i].obj, list[i].mode, &lp); list[i].obj, list[i].mode, &lp);
if (ret == 0) if (ret == 0) {
list[i].lock = LOCK_TO_OFFSET(lt, lp); list[i].lock = LOCK_TO_OFFSET(lt, lp);
lt->region->nrequests++;
}
break; break;
case DB_LOCK_PUT: case DB_LOCK_PUT:
lp = OFFSET_TO_LOCK(lt, list[i].lock); 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: case DB_LOCK_PUT_OBJ:
/* Look up the object in the hash table. */ /* 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, list[i].obj, sh_obj, lt->region->table_size,
__lock_ohash, __lock_cmp); __lock_ohash, __lock_cmp);
if (sh_obj == NULL) { if (sh_obj == NULL) {
@ -596,8 +598,8 @@ __lock_put_internal(lt, lockp, do_all)
/* Check if object should be reclaimed. */ /* Check if object should be reclaimed. */
if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL) { if (SH_TAILQ_FIRST(&sh_obj->holders, __db_lock) == NULL) {
__db_hashremove_el(lt->hashtab, __db_lockobj, links, sh_obj, HASHREMOVE_EL(lt->hashtab, __db_lockobj,
lt->region->table_size, __lock_lhash); links, sh_obj, lt->region->table_size, __lock_lhash);
__db_shalloc_free(lt->mem, SH_DBT_PTR(&sh_obj->lockobj)); __db_shalloc_free(lt->mem, SH_DBT_PTR(&sh_obj->lockobj));
SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, sh_obj, links, SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, sh_obj, links,
__db_lockobj); __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 * 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 * 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 * 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 * OR anyone on the waiters list. The reason that we don't grant if
* new lock on the end of the waiters list. * 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); for (lp = SH_TAILQ_FIRST(&sh_obj->holders, __db_lock);
lp != NULL; lp != NULL;
@ -1042,7 +1048,7 @@ __lock_dump_locker(lt, op)
ptr = SH_DBT_PTR(&op->lockobj); ptr = SH_DBT_PTR(&op->lockobj);
memcpy(&locker, ptr, sizeof(u_int32_t)); 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); lp = SH_LIST_FIRST(&op->heldby, __db_lock);
if (lp == NULL) { if (lp == NULL) {
@ -1095,7 +1101,7 @@ __lock_is_locked(lt, locker, dbt, mode)
lrp = lt->region; lrp = lt->region;
/* Look up the object in the hash table. */ /* 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); dbt, sh_obj, lrp->table_size, __lock_ohash, __lock_cmp);
if (sh_obj == NULL) if (sh_obj == NULL)
return (0); return (0);
@ -1171,7 +1177,7 @@ __lock_printlock(lt, lp, ispgno)
stat = "UNKNOWN"; stat = "UNKNOWN";
break; 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); (u_long)lp->holder, mode, (u_long)lp->refcount, stat);
lockobj = (DB_LOCKOBJ *)((u_int8_t *)lp + lp->obj); 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. */ /* Look up the object in the hash table. */
if (type == DB_LOCK_OBJTYPE) { 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); lrp->table_size, __lock_ohash, __lock_cmp);
obj_size = dbt->size; obj_size = dbt->size;
} else { } else {
__db_hashlookup(lt->hashtab, __db_lockobj, links, locker, HASHLOOKUP(lt->hashtab, __db_lockobj, links, locker,
sh_obj, lrp->table_size, __lock_locker_hash, sh_obj, lrp->table_size, __lock_locker_hash,
__lock_locker_cmp); __lock_locker_cmp);
obj_size = sizeof(locker); obj_size = sizeof(locker);
@ -1288,8 +1294,8 @@ __lock_getobj(lt, locker, dbt, type, objp)
sh_obj->lockobj.size = obj_size; sh_obj->lockobj.size = obj_size;
sh_obj->lockobj.off = SH_PTR_TO_OFF(&sh_obj->lockobj, p); sh_obj->lockobj.off = SH_PTR_TO_OFF(&sh_obj->lockobj, p);
__db_hashinsert(lt->hashtab, __db_lockobj, links, sh_obj, HASHINSERT(lt->hashtab,
lrp->table_size, __lock_lhash); __db_lockobj, links, sh_obj, lrp->table_size, __lock_lhash);
if (type == DB_LOCK_LOCKER) if (type == DB_LOCK_LOCKER)
lrp->nlockers++; lrp->nlockers++;
@ -1325,8 +1331,8 @@ __lock_freeobj(lt, obj)
DB_LOCKTAB *lt; DB_LOCKTAB *lt;
DB_LOCKOBJ *obj; DB_LOCKOBJ *obj;
{ {
__db_hashremove_el(lt->hashtab, __db_lockobj, links, HASHREMOVE_EL(lt->hashtab,
obj, lt->region->table_size, __lock_lhash); __db_lockobj, links, obj, lt->region->table_size, __lock_lhash);
__db_shalloc_free(lt->mem, SH_DBT_PTR(&obj->lockobj)); __db_shalloc_free(lt->mem, SH_DBT_PTR(&obj->lockobj));
SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, obj, links, __db_lockobj); SH_TAILQ_INSERT_HEAD(&lt->region->free_objs, obj, links, __db_lockobj);
} }

View File

@ -11,7 +11,7 @@
static const char copyright[] = static const char copyright[] =
"@(#) Copyright (c) 1997\n\ "@(#) Copyright (c) 1997\n\
Sleepycat Software Inc. All rights reserved.\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 #endif
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -300,8 +300,8 @@ retry: count = lt->region->nlockers;
for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock); for (lp = SH_TAILQ_FIRST(&op->holders, __db_lock);
lp != NULL; lp != NULL;
lp = SH_TAILQ_NEXT(lp, links, __db_lock)) { lp = SH_TAILQ_NEXT(lp, links, __db_lock)) {
if ((__set_errno(__lock_getobj(lt, lp->holder, if (__lock_getobj(lt, lp->holder,
NULL, DB_LOCK_LOCKER, &lockerp))) != 0) { NULL, DB_LOCK_LOCKER, &lockerp) != 0) {
__db_err(dbenv, __db_err(dbenv,
"warning unable to find object"); "warning unable to find object");
continue; continue;
@ -472,8 +472,7 @@ __dd_debug(dbenv, idmap, bitmap, nlockers)
* Alloc space to print 10 bytes per item waited on. * Alloc space to print 10 bytes per item waited on.
*/ */
if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) { if ((msgbuf = (char *)malloc((nlockers + 1) * 10 + 64)) == NULL) {
__set_errno(ENOMEM); __db_err(dbenv, "%s", strerror(ENOMEM));
__db_err(dbenv, "%s", strerror(errno));
return; return;
} }

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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 "txn_auto.h"
#include "common_ext.h" #include "common_ext.h"
static int __log_recover __P((DB_ENV *, DB_LOG *)); static int __log_recover __P((DB_LOG *));
/* /*
* log_open -- * log_open --
@ -70,14 +70,15 @@ log_open(path, flags, mode, dbenv, lpp)
if ((dblp = (DB_LOG *)calloc(1, sizeof(DB_LOG))) == NULL) if ((dblp = (DB_LOG *)calloc(1, sizeof(DB_LOG))) == NULL)
return (ENOMEM); return (ENOMEM);
if (path != NULL && (dblp->dir = strdup(path)) == NULL) {
free(dblp);
return (ENOMEM);
}
dblp->dbenv = dbenv; dblp->dbenv = dbenv;
dblp->lfd = -1; dblp->lfd = -1;
ZERO_LSN(dblp->c_lsn); ZERO_LSN(dblp->c_lsn);
dblp->c_fd = -1; 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 * The log region isn't fixed size because we store the registered
@ -114,7 +115,7 @@ retry: if (LF_ISSET(DB_CREATE)) {
newregion = 1; newregion = 1;
} else if (ret != EEXIST) } else if (ret != EEXIST)
return (ret); goto err;
} }
/* If we didn't or couldn't create the region, try and join it. */ /* 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); (void)__db_sleep(1, 0);
goto retry; goto retry;
} }
return (ret); goto err;
} }
/* Set up the common information. */ /* 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->addr = (u_int8_t *)dblp->maddr + sizeof(LOG);
dblp->fd = fd; 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 * If doing recovery, try and recover any previous log files
* before releasing the lock. * before releasing the lock.
*/ */
if (newregion) { if (newregion) {
if ((ret = __log_recover(dbenv, dblp)) != 0) { ret = __log_recover(dblp);
log_unlink(path, 1, dbenv); UNLOCK_LOGREGION(dblp);
if (ret != 0) {
(void)log_close(dblp);
(void)log_unlink(path, 1, dbenv);
return (ret); return (ret);
} }
UNLOCK_LOGREGION(dblp);
} }
*lpp = dblp; *lpp = dblp;
return (0); 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. * Recover a log.
*/ */
static int static int
__log_recover(dbenv, dblp) __log_recover(dblp)
DB_ENV *dbenv;
DB_LOG *dblp; DB_LOG *dblp;
{ {
DBT dbt; DBT dbt;
@ -173,14 +203,14 @@ __log_recover(dbenv, dblp)
* Find a log file. If none exist, we simply return, leaving * Find a log file. If none exist, we simply return, leaving
* everything initialized to a new log. * everything initialized to a new log.
*/ */
if ((ret = __log_find(dbenv, lp, &cnt)) != 0) if ((ret = __log_find(dblp, &cnt)) != 0)
return (ret); return (ret);
if (cnt == 0) if (cnt == 0)
return (0); return (0);
/* We have a log file name, find the last one. */ /* We have a log file name, find the last one. */
while (cnt < MAXLFNAME) while (cnt < MAXLFNAME)
if (__log_valid(dbenv, lp, ++cnt) != 0) { if (__log_valid(dblp, lp, ++cnt) != 0) {
--cnt; --cnt;
break; break;
} }
@ -263,7 +293,7 @@ __log_recover(dbenv, dblp)
lp->c_lsn.offset = 0; lp->c_lsn.offset = 0;
} }
__db_err(dbenv, __db_err(dblp->dbenv,
"Recovering the log: last valid LSN: file: %lu offset %lu", "Recovering the log: last valid LSN: file: %lu offset %lu",
(u_long)lp->lsn.file, (u_long)lp->lsn.offset); (u_long)lp->lsn.file, (u_long)lp->lsn.offset);
@ -277,12 +307,11 @@ __log_recover(dbenv, dblp)
* __log_find -- * __log_find --
* Try to find a log file. * Try to find a log file.
* *
* PUBLIC: int __log_find __P((DB_ENV *, LOG *, int *)); * PUBLIC: int __log_find __P((DB_LOG *, int *));
*/ */
int int
__log_find(dbenv, lp, valp) __log_find(dblp, valp)
DB_ENV *dbenv; DB_LOG *dblp;
LOG *lp;
int *valp; int *valp;
{ {
int cnt, fcnt, logval, ret; int cnt, fcnt, logval, ret;
@ -290,7 +319,7 @@ __log_find(dbenv, lp, valp)
char **names, *p, *q; char **names, *p, *q;
/* Find the directory name. */ /* Find the directory name. */
if ((ret = __log_name(dbenv, 1, &p)) != 0) if ((ret = __log_name(dblp, 1, &p)) != 0)
return (ret); return (ret);
if ((q = __db_rpath(p)) == NULL) if ((q = __db_rpath(p)) == NULL)
dir = PATH_DOT; dir = PATH_DOT;
@ -300,7 +329,7 @@ __log_find(dbenv, lp, valp)
} }
/* Get the list of file names. */ /* Get the list of file names. */
ret = __db_dir(dbenv, dir, &names, &fcnt); ret = __db_dir(dblp->dbenv, dir, &names, &fcnt);
FREES(p); FREES(p);
if (ret != 0) if (ret != 0)
return (ret); return (ret);
@ -314,14 +343,14 @@ __log_find(dbenv, lp, valp)
if (strncmp(names[cnt], "log.", sizeof("log.") - 1) == 0) { if (strncmp(names[cnt], "log.", sizeof("log.") - 1) == 0) {
logval = atoi(names[cnt] + 4); logval = atoi(names[cnt] + 4);
if (logval != 0 && if (logval != 0 &&
__log_valid(dbenv, lp, logval) == 0) { __log_valid(dblp, dblp->lp, logval) == 0) {
*valp = logval; *valp = logval;
break; break;
} }
} }
/* Discard the list. */ /* Discard the list. */
__db_dirf(dbenv, names, fcnt); __db_dirf(dblp->dbenv, names, fcnt);
return (ret); return (ret);
} }
@ -330,11 +359,11 @@ __log_find(dbenv, lp, valp)
* log_valid -- * log_valid --
* Validate a log file. * Validate a log file.
* *
* PUBLIC: int __log_valid __P((DB_ENV *, LOG *, int)); * PUBLIC: int __log_valid __P((DB_LOG *, LOG *, int));
*/ */
int int
__log_valid(dbenv, lp, cnt) __log_valid(dblp, lp, cnt)
DB_ENV *dbenv; DB_LOG *dblp;
LOG *lp; LOG *lp;
int cnt; int cnt;
{ {
@ -343,7 +372,7 @@ __log_valid(dbenv, lp, cnt)
int fd, ret; int fd, ret;
char *p; char *p;
if ((ret = __log_name(dbenv, cnt, &p)) != 0) if ((ret = __log_name(dblp, cnt, &p)) != 0)
return (ret); return (ret);
fd = -1; fd = -1;
@ -357,7 +386,7 @@ __log_valid(dbenv, lp, cnt)
ret = EIO; ret = EIO;
if (fd != -1) { if (fd != -1) {
(void)__db_close(fd); (void)__db_close(fd);
__db_err(dbenv, __db_err(dblp->dbenv,
"Ignoring log file: %s: %s", p, strerror(ret)); "Ignoring log file: %s: %s", p, strerror(ret));
} }
goto err; goto err;
@ -365,14 +394,14 @@ __log_valid(dbenv, lp, cnt)
(void)__db_close(fd); (void)__db_close(fd);
if (persist.magic != DB_LOGMAGIC) { if (persist.magic != DB_LOGMAGIC) {
__db_err(dbenv, __db_err(dblp->dbenv,
"Ignoring log file: %s: magic number %lx, not %lx", "Ignoring log file: %s: magic number %lx, not %lx",
p, (u_long)persist.magic, (u_long)DB_LOGMAGIC); p, (u_long)persist.magic, (u_long)DB_LOGMAGIC);
ret = EINVAL; ret = EINVAL;
goto err; goto err;
} }
if (persist.version < DB_LOGOLDVER || persist.version > DB_LOGVERSION) { if (persist.version < DB_LOGOLDVER || persist.version > DB_LOGVERSION) {
__db_err(dbenv, __db_err(dblp->dbenv,
"Ignoring log file: %s: unsupported log version %lu", "Ignoring log file: %s: unsupported log version %lu",
p, (u_long)persist.version); p, (u_long)persist.version);
ret = EINVAL; ret = EINVAL;
@ -401,6 +430,13 @@ log_close(dblp)
ret = 0; 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. */ /* Close the region. */
if ((t_ret = if ((t_ret =
__db_rclose(dblp->dbenv, dblp->fd, dblp->maddr)) != 0 && ret == 0) __db_rclose(dblp->dbenv, dblp->fd, dblp->maddr)) != 0 && ret == 0)
@ -414,10 +450,12 @@ log_close(dblp)
if (dblp->c_fd != -1 && if (dblp->c_fd != -1 &&
(t_ret = __db_close(dblp->c_fd)) != 0 && ret == 0) (t_ret = __db_close(dblp->c_fd)) != 0 && ret == 0)
ret = t_ret; ret = t_ret;
/* Free the structure. */
if (dblp->dbentry != NULL) if (dblp->dbentry != NULL)
FREE(dblp->dbentry, (dblp->dbentry_cnt * sizeof(DB_ENTRY))); FREE(dblp->dbentry, (dblp->dbentry_cnt * sizeof(DB_ENTRY)));
if (dblp->dir != NULL)
FREES(dblp->dir);
/* Free the structure. */
FREE(dblp, sizeof(DB_LOG)); FREE(dblp, sizeof(DB_LOG));
return (ret); return (ret);

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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 "clib_ext.h"
#include "common_ext.h" #include "common_ext.h"
static int absname __P((char *, char *, char **)); static int __absname __P((char *, char *, char **));
static int build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t))); static int __build_data __P((DB_LOG *, char *, char ***, void *(*)(size_t)));
static int cmpfunc __P((const void *, const void *)); static int __cmpfunc __P((const void *, const void *));
static int usermem __P((char ***, void *(*)(size_t))); static int __usermem __P((char ***, void *(*)(size_t)));
/* /*
* log_archive -- * log_archive --
* Supporting function for db_archive(1). * Supporting function for db_archive(1).
*/ */
int int
log_archive(logp, listp, flags, db_malloc) log_archive(dblp, listp, flags, db_malloc)
DB_LOG *logp; DB_LOG *dblp;
char ***listp; char ***listp;
int flags; int flags;
void *(*db_malloc) __P((size_t)); 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) #define OKFLAGS (DB_ARCH_ABS | DB_ARCH_DATA | DB_ARCH_LOG)
if (flags != 0) { if (flags != 0) {
if ((ret = if ((ret =
__db_fchk(logp->dbenv, "log_archive", flags, OKFLAGS)) != 0) __db_fchk(dblp->dbenv, "log_archive", flags, OKFLAGS)) != 0)
return (ret); return (ret);
if ((ret = if ((ret =
__db_fcchk(logp->dbenv, __db_fcchk(dblp->dbenv,
"log_archive", flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0) "log_archive", flags, DB_ARCH_DATA, DB_ARCH_LOG)) != 0)
return (ret); return (ret);
} }
@ -76,19 +76,19 @@ log_archive(logp, listp, flags, db_malloc)
switch (LF_ISSET(~DB_ARCH_ABS)) { switch (LF_ISSET(~DB_ARCH_ABS)) {
case DB_ARCH_DATA: case DB_ARCH_DATA:
return (build_data(logp, pref, listp, db_malloc)); return (__build_data(dblp, pref, listp, db_malloc));
case DB_ARCH_LOG: case DB_ARCH_LOG:
memset(&rec, 0, sizeof(rec)); 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); 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); return (ret);
if (F_ISSET(logp, DB_AM_THREAD)) if (F_ISSET(dblp, DB_AM_THREAD))
free(rec.data); free(rec.data);
fnum = stable_lsn.file; fnum = stable_lsn.file;
break; break;
case 0: case 0:
if ((ret = __log_findckp(logp, &stable_lsn)) != 0) { if ((ret = __log_findckp(dblp, &stable_lsn)) != 0) {
if (ret != DB_NOTFOUND) if (ret != DB_NOTFOUND)
return (ret); return (ret);
*listp = NULL; *listp = NULL;
@ -108,7 +108,7 @@ log_archive(logp, listp, flags, db_malloc)
/* Build an array of the file names. */ /* Build an array of the file names. */
for (n = 0; fnum > 0; --fnum) { 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; goto err;
if (__db_exists(name, NULL) != 0) if (__db_exists(name, NULL) != 0)
break; break;
@ -123,7 +123,7 @@ log_archive(logp, listp, flags, db_malloc)
} }
if (LF_ISSET(DB_ARCH_ABS)) { if (LF_ISSET(DB_ARCH_ABS)) {
if ((ret = absname(pref, name, &array[n])) != 0) if ((ret = __absname(pref, name, &array[n])) != 0)
goto err; goto err;
FREES(name); FREES(name);
} else if ((p = __db_rpath(name)) != NULL) { } else if ((p = __db_rpath(name)) != NULL) {
@ -146,10 +146,10 @@ log_archive(logp, listp, flags, db_malloc)
} }
/* Sort the list. */ /* Sort the list. */
qsort(array, (size_t)n, sizeof(char *), cmpfunc); qsort(array, (size_t)n, sizeof(char *), __cmpfunc);
/* Rework the memory. */ /* Rework the memory. */
if ((ret = usermem(&array, db_malloc)) != 0) if ((ret = __usermem(&array, db_malloc)) != 0)
goto err; goto err;
*listp = array; *listp = array;
@ -164,12 +164,12 @@ err: if (array != NULL) {
} }
/* /*
* build_data -- * __build_data --
* Build a list of datafiles for return. * Build a list of datafiles for return.
*/ */
static int static int
build_data(logp, pref, listp, db_malloc) __build_data(dblp, pref, listp, db_malloc)
DB_LOG *logp; DB_LOG *dblp;
char *pref, ***listp; char *pref, ***listp;
void *(*db_malloc) __P((size_t)); void *(*db_malloc) __P((size_t));
{ {
@ -187,19 +187,19 @@ build_data(logp, pref, listp, db_malloc)
array[0] = NULL; array[0] = NULL;
memset(&rec, 0, sizeof(rec)); 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); F_SET(&rec, DB_DBT_MALLOC);
for (n = 0, ret = log_get(logp, &lsn, &rec, DB_FIRST); for (n = 0, ret = log_get(dblp, &lsn, &rec, DB_FIRST);
ret == 0; ret = log_get(logp, &lsn, &rec, DB_NEXT)) { ret == 0; ret = log_get(dblp, &lsn, &rec, DB_NEXT)) {
if (rec.size < sizeof(rectype)) { if (rec.size < sizeof(rectype)) {
ret = EINVAL; ret = EINVAL;
__db_err(logp->dbenv, "log_archive: bad log record"); __db_err(dblp->dbenv, "log_archive: bad log record");
goto lg_free; goto lg_free;
} }
memcpy(&rectype, rec.data, sizeof(rectype)); memcpy(&rectype, rec.data, sizeof(rectype));
if (rectype != DB_log_register) { if (rectype != DB_log_register) {
if (F_ISSET(logp, DB_AM_THREAD)) { if (F_ISSET(dblp, DB_AM_THREAD)) {
free(rec.data); free(rec.data);
rec.data = NULL; rec.data = NULL;
} }
@ -207,7 +207,7 @@ build_data(logp, pref, listp, db_malloc)
} }
if ((ret = __log_register_read(rec.data, &argp)) != 0) { if ((ret = __log_register_read(rec.data, &argp)) != 0) {
ret = EINVAL; ret = EINVAL;
__db_err(logp->dbenv, __db_err(dblp->dbenv,
"log_archive: unable to read log record"); "log_archive: unable to read log record");
goto lg_free; goto lg_free;
} }
@ -231,7 +231,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
array[++n] = NULL; array[++n] = NULL;
free(argp); free(argp);
if (F_ISSET(logp, DB_AM_THREAD)) { if (F_ISSET(dblp, DB_AM_THREAD)) {
free(rec.data); free(rec.data);
rec.data = NULL; rec.data = NULL;
} }
@ -245,7 +245,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
} }
/* Sort the list. */ /* 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 * 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. */ /* 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) DB_APP_DATA, NULL, array[last], NULL, &real_name)) != 0)
goto err2; goto err2;
@ -284,7 +284,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
FREES(array[last]); FREES(array[last]);
array[last] = NULL; array[last] = NULL;
if (pref != NULL) { if (pref != NULL) {
ret = absname(pref, real_name, &array[last]); ret = __absname(pref, real_name, &array[last]);
FREES(real_name); FREES(real_name);
if (ret != 0) if (ret != 0)
goto err2; goto err2;
@ -302,7 +302,7 @@ lg_free: if (F_ISSET(&rec, DB_DBT_MALLOC) && rec.data != NULL)
array[last] = NULL; array[last] = NULL;
/* Rework the memory. */ /* Rework the memory. */
if ((ret = usermem(&array, db_malloc)) != 0) if ((ret = __usermem(&array, db_malloc)) != 0)
goto err1; goto err1;
*listp = array; *listp = array;
@ -327,11 +327,11 @@ err1: if (array != NULL) {
} }
/* /*
* absname -- * __absname --
* Return an absolute path name for the file. * Return an absolute path name for the file.
*/ */
static int static int
absname(pref, name, newnamep) __absname(pref, name, newnamep)
char *pref, *name, **newnamep; char *pref, *name, **newnamep;
{ {
size_t l_pref, l_name; 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. * Create a single chunk of memory that holds the returned information.
* If the user has their own malloc routine, use it. * If the user has their own malloc routine, use it.
*/ */
static int static int
usermem(listp, func) __usermem(listp, func)
char ***listp; char ***listp;
void *(*func) __P((size_t)); void *(*func) __P((size_t));
{ {
@ -406,7 +406,7 @@ usermem(listp, func)
} }
static int static int
cmpfunc(p1, p2) __cmpfunc(p1, p2)
const void *p1, *p2; const void *p1, *p2;
{ {
return (strcmp(*((char **)p1), *((char **)p2))); return (strcmp(*((char **)p1), *((char **)p2)));

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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 * Find any log file. Note, we may have only entered records
* in the buffer, and not yet written a log file. * 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, __db_err(dblp->dbenv,
"log_get: unable to find the first record: no log files found."); "log_get: unable to find the first record: no log files found.");
goto err2; goto err2;
@ -157,7 +157,7 @@ __log_get(dblp, alsn, dbt, flags, silent)
/* Now go backwards to find the smallest one. */ /* Now go backwards to find the smallest one. */
for (; cnt > 1; --cnt) for (; cnt > 1; --cnt)
if (__log_valid(dblp->dbenv, NULL, cnt) != 0) { if (__log_valid(dblp, NULL, cnt) != 0) {
++cnt; ++cnt;
break; break;
} }
@ -223,7 +223,7 @@ retry:
* Acquire a file descriptor. * Acquire a file descriptor.
*/ */
if (dblp->c_fd == -1) { 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; goto err1;
if ((ret = __db_fdopen(np, DB_RDONLY | DB_SEQUENTIAL, if ((ret = __db_fdopen(np, DB_RDONLY | DB_SEQUENTIAL,
DB_RDONLY | DB_SEQUENTIAL, 0, &dblp->c_fd)) != 0) { DB_RDONLY | DB_SEQUENTIAL, 0, &dblp->c_fd)) != 0) {
@ -319,6 +319,7 @@ retry:
&dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0) &dblp->c_dbt.data, &dblp->c_dbt.ulen, NULL)) != 0)
goto err1; goto err1;
free(tbuf); free(tbuf);
tbuf = NULL;
cksum: if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) { cksum: if (hdr.cksum != __ham_func4(dbt->data, dbt->size)) {
if (!silent) if (!silent)

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -416,7 +416,7 @@ log_file(dblp, lsn, namep, len)
LOCK_LOGREGION(dblp); LOCK_LOGREGION(dblp);
ret = __log_name(dblp->dbenv, lsn->file, &p); ret = __log_name(dblp, lsn->file, &p);
UNLOCK_LOGREGION(dblp); UNLOCK_LOGREGION(dblp);
@ -453,14 +453,14 @@ __log_newfd(dblp)
/* Get the path of the new file and open it. */ /* Get the path of the new file and open it. */
dblp->lfname = dblp->lp->lsn.file; 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); return (ret);
if ((ret = __db_fdopen(p, if ((ret = __db_fdopen(p,
DB_CREATE | DB_SEQUENTIAL, DB_CREATE | DB_SEQUENTIAL,
DB_CREATE | DB_SEQUENTIAL, DB_CREATE | DB_SEQUENTIAL,
dblp->lp->persist.mode, &dblp->lfd)) != 0) dblp->lp->persist.mode, &dblp->lfd)) != 0)
__db_err(dblp->dbenv, __db_err(dblp->dbenv,
"log_put: %s: %s", p, strerror(errno)); "log_put: %s: %s", p, strerror(ret));
FREES(p); FREES(p);
return (ret); return (ret);
} }
@ -469,16 +469,17 @@ __log_newfd(dblp)
* __log_name -- * __log_name --
* Return the log name for a particular file. * 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 int
__log_name(dbenv, fn, np) __log_name(dblp, fileno, namep)
DB_ENV *dbenv; DB_LOG *dblp;
int fn; char **namep;
char **np; int fileno;
{ {
char name[sizeof(LFNAME) + 10]; char name[sizeof(LFNAME) + 10];
(void)snprintf(name, sizeof(name), LFNAME, fn); (void)snprintf(name, sizeof(name), LFNAME, fileno);
return (__db_appname(dbenv, DB_APP_LOG, NULL, name, NULL, np)); return (__db_appname(dblp->dbenv,
DB_APP_LOG, dblp->dir, name, NULL, namep));
} }

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -190,7 +190,12 @@ log_unregister(dblp, fid)
SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname); SH_TAILQ_REMOVE(&dblp->lp->fq, fnp, q, __fname);
__db_shalloc_free(dblp->addr, fnp); __db_shalloc_free(dblp->addr, fnp);
/* Remove from the process local table. */ /*
* 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); __log_rem_logid(dblp, fid);
ret1: UNLOCK_LOGREGION(dblp); ret1: UNLOCK_LOGREGION(dblp);

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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 * If we find a descriptor on the file that's not open for writing, we
* try and upgrade it to make it writeable. * try and upgrade it to make it writeable.
*/ */
LOCKHANDLE(dbmp, &dbmp->mutex); LOCKHANDLE(dbmp, dbmp->mutexp);
for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq); for (dbmfp = TAILQ_FIRST(&dbmp->dbmfq);
dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q)) dbmfp != NULL; dbmfp = TAILQ_NEXT(dbmfp, q))
if (dbmfp->mfp == mfp) { if (dbmfp->mfp == mfp) {
@ -64,7 +64,7 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
return (0); return (0);
break; break;
} }
UNLOCKHANDLE(dbmp, &dbmp->mutex); UNLOCKHANDLE(dbmp, dbmp->mutexp);
if (dbmfp != NULL) if (dbmfp != NULL)
goto found; goto found;
@ -75,12 +75,12 @@ __memp_bhwrite(dbmp, mfp, bhp, restartp, wrotep)
* nothing we can do. * nothing we can do.
*/ */
if (mfp->ftype != 0) { if (mfp->ftype != 0) {
LOCKHANDLE(dbmp, &dbmp->mutex); LOCKHANDLE(dbmp, dbmp->mutexp);
for (mpreg = LIST_FIRST(&dbmp->dbregq); for (mpreg = LIST_FIRST(&dbmp->dbregq);
mpreg != NULL; mpreg = LIST_NEXT(mpreg, q)) mpreg != NULL; mpreg = LIST_NEXT(mpreg, q))
if (mpreg->ftype == mfp->ftype) if (mpreg->ftype == mfp->ftype)
break; break;
UNLOCKHANDLE(dbmp, &dbmp->mutex); UNLOCKHANDLE(dbmp, dbmp->mutexp);
if (mpreg == NULL) if (mpreg == NULL)
return (0); return (0);
} }
@ -135,19 +135,19 @@ __memp_pgread(dbmfp, bhp, can_create)
* Seek to the page location. * Seek to the page location.
*/ */
ret = 0; ret = 0;
LOCKHANDLE(dbmp, &dbmfp->mutex); LOCKHANDLE(dbmp, dbmfp->mutexp);
if (dbmfp->fd == -1 || (ret = if (dbmfp->fd == -1 || (ret =
__db_lseek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0) { __db_lseek(dbmfp->fd, pagesize, bhp->pgno, 0, SEEK_SET)) != 0) {
if (!can_create) { if (!can_create) {
if (dbmfp->fd == -1) if (dbmfp->fd == -1)
ret = EINVAL; ret = EINVAL;
UNLOCKHANDLE(dbmp, &dbmfp->mutex); UNLOCKHANDLE(dbmp, dbmfp->mutexp);
__db_err(dbmp->dbenv, __db_err(dbmp->dbenv,
"%s: page %lu doesn't exist, create flag not set", "%s: page %lu doesn't exist, create flag not set",
dbmfp->path, (u_long)bhp->pgno); dbmfp->path, (u_long)bhp->pgno);
goto err; goto err;
} }
UNLOCKHANDLE(dbmp, &dbmfp->mutex); UNLOCKHANDLE(dbmp, dbmfp->mutexp);
/* Clear any uninitialized data. */ /* Clear any uninitialized data. */
memset(bhp->buf, 0, pagesize); memset(bhp->buf, 0, pagesize);
@ -159,7 +159,7 @@ __memp_pgread(dbmfp, bhp, can_create)
* any valid data is preserved. * any valid data is preserved.
*/ */
ret = __db_read(dbmfp->fd, bhp->buf, pagesize, &nr); ret = __db_read(dbmfp->fd, bhp->buf, pagesize, &nr);
UNLOCKHANDLE(dbmp, &dbmfp->mutex); UNLOCKHANDLE(dbmp, dbmfp->mutexp);
if (ret != 0) if (ret != 0)
goto err; goto err;
@ -268,10 +268,10 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
} }
/* Temporary files may not yet have been created. */ /* 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, if (dbmfp->fd == -1 && ((ret = __db_appname(dbenv, DB_APP_TMP,
NULL, NULL, &dbmfp->fd, NULL)) != 0 || dbmfp->fd == -1)) { 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"); __db_err(dbenv, "unable to create temporary backing file");
goto err; goto err;
} }
@ -282,7 +282,7 @@ __memp_pgwrite(dbmfp, bhp, restartp, wrotep)
fail = "seek"; fail = "seek";
else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0) else if ((ret = __db_write(dbmfp->fd, bhp->buf, pagesize, &nw)) != 0)
fail = "write"; fail = "write";
UNLOCKHANDLE(dbmp, &dbmfp->mutex); UNLOCKHANDLE(dbmp, dbmfp->mutexp);
if (ret != 0) { if (ret != 0) {
/* /*
* XXX * XXX
@ -380,7 +380,7 @@ __memp_pg(dbmfp, bhp, is_pgin)
dbmp = dbmfp->dbmp; dbmp = dbmfp->dbmp;
mfp = dbmfp->mfp; mfp = dbmfp->mfp;
LOCKHANDLE(dbmp, &dbmp->mutex); LOCKHANDLE(dbmp, dbmp->mutexp);
ftype = mfp->ftype; ftype = mfp->ftype;
for (mpreg = LIST_FIRST(&dbmp->dbregq); for (mpreg = LIST_FIRST(&dbmp->dbregq);
@ -394,7 +394,7 @@ __memp_pg(dbmfp, bhp, is_pgin)
dbt.data = ADDR(dbmp, mfp->pgcookie_off); dbt.data = ADDR(dbmp, mfp->pgcookie_off);
dbtp = &dbt; dbtp = &dbt;
} }
UNLOCKHANDLE(dbmp, &dbmp->mutex); UNLOCKHANDLE(dbmp, dbmp->mutexp);
if (is_pgin) { if (is_pgin) {
if (mpreg->pgin != NULL && (ret = if (mpreg->pgin != NULL && (ret =
@ -408,11 +408,11 @@ __memp_pg(dbmfp, bhp, is_pgin)
} }
if (mpreg == NULL) if (mpreg == NULL)
UNLOCKHANDLE(dbmp, &dbmp->mutex); UNLOCKHANDLE(dbmp, dbmp->mutexp);
return (0); return (0);
err: UNLOCKHANDLE(dbmp, &dbmp->mutex); err: UNLOCKHANDLE(dbmp, dbmp->mutexp);
__db_err(dbmp->dbenv, "%s: %s failed for page %lu", __db_err(dbmp->dbenv, "%s: %s failed for page %lu",
dbmfp->path, is_pgin ? "pgin" : "pgout", (u_long)bhp->pgno); dbmfp->path, is_pgin ? "pgin" : "pgout", (u_long)bhp->pgno);
return (ret); return (ret);

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -35,7 +35,7 @@ int
memp_fget(dbmfp, pgnoaddr, flags, addrp) memp_fget(dbmfp, pgnoaddr, flags, addrp)
DB_MPOOLFILE *dbmfp; DB_MPOOLFILE *dbmfp;
db_pgno_t *pgnoaddr; db_pgno_t *pgnoaddr;
u_long flags; int flags;
void *addrp; void *addrp;
{ {
BH *bhp, *tbhp; BH *bhp, *tbhp;
@ -293,7 +293,7 @@ found: /* Increment the reference count. */
__db_err(dbmp->dbenv, __db_err(dbmp->dbenv,
"%s: too many references to page %lu", "%s: too many references to page %lu",
dbmfp->path, bhp->pgno); dbmfp->path, bhp->pgno);
ret = EAGAIN; ret = EINVAL;
goto err; goto err;
} }
++bhp->ref; ++bhp->ref;
@ -337,9 +337,9 @@ found: /* Increment the reference count. */
++mfp->stat.st_cache_hit; ++mfp->stat.st_cache_hit;
} }
mapret: LOCKHANDLE(dbmp, &dbmfp->mutex); mapret: LOCKHANDLE(dbmp, dbmfp->mutexp);
++dbmfp->pinref; ++dbmfp->pinref;
UNLOCKHANDLE(dbmp, &dbmfp->mutex); UNLOCKHANDLE(dbmp, dbmfp->mutexp);
if (0) { if (0) {
err: /* err: /*

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #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" #include "common_ext.h"
static int __memp_mf_close __P((DB_MPOOL *, DB_MPOOLFILE *)); static int __memp_mf_close __P((DB_MPOOL *, DB_MPOOLFILE *));
static int __memp_mf_open __P((DB_MPOOL *, DB_MPOOLFILE *, static int __memp_mf_open __P((DB_MPOOL *,
int, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **)); DB_MPOOLFILE *, int, size_t, int, DBT *, u_int8_t *, int, MPOOLFILE **));
/* /*
* memp_fopen -- * memp_fopen --
@ -97,7 +97,6 @@ __memp_fopen(dbmp, path,
path == NULL ? TEMPORARY : path, strerror(ENOMEM)); path == NULL ? TEMPORARY : path, strerror(ENOMEM));
return (ENOMEM); return (ENOMEM);
} }
LOCKINIT(dbmp, &dbmfp->mutex);
dbmfp->dbmp = dbmp; dbmfp->dbmp = dbmp;
dbmfp->fd = -1; dbmfp->fd = -1;
if (LF_ISSET(DB_RDONLY)) 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) if (needlock)
LOCKREGION(dbmp); LOCKREGION(dbmp);
ret = __memp_mf_open(dbmp, dbmfp, ftype, ret = __memp_mf_open(dbmp, dbmfp, ftype, pagesize,
F_ISSET(dbmfp, MP_READONLY), pagesize,
lsn_offset, pgcookie, fileid, F_ISSET(dbmfp, MP_PATH_TEMP), &mfp); 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) if (needlock)
UNLOCKREGION(dbmp); UNLOCKREGION(dbmp);
if (ret != 0) if (ret != 0)
goto err; goto err;
@ -156,11 +162,11 @@ __memp_fopen(dbmp, path,
/* /*
* If a file: * If a file:
*
* + is read-only * + is read-only
* + isn't temporary
* + doesn't require any pgin/pgout support * + doesn't require any pgin/pgout support
* + is less than mp_mmapsize bytes in size. * + the DB_NOMMAP flag wasn't set
* + and 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 * 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 * 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. * flatly impossible. Hope that mmap fails if the file is too large.
*/ */
#define DB_MAXMMAPSIZE (10 * 1024 * 1024) /* 10 Mb. */ #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; 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) { if (mfp->can_mmap) {
dbmfp->len = size; dbmfp->len = size;
if (__db_mmap(dbmfp->fd, dbmfp->len, 1, 1, &dbmfp->addr) != 0) { 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); TAILQ_INSERT_TAIL(&dbmp->dbmfq, dbmfp, q);
UNLOCKHANDLE(dbmp, &dbmp->mutex); UNLOCKHANDLE(dbmp, dbmp->mutexp);
*retp = dbmfp; *retp = dbmfp;
return (0); 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); FREES(dbmfp->path);
if (dbmfp->fd != -1) if (dbmfp->fd != -1)
(void)__db_close(dbmfp->fd); (void)__db_close(dbmfp->fd);
@ -211,10 +230,10 @@ err: if (F_ISSET(dbmfp, MP_PATH_ALLOC))
*/ */
static int static int
__memp_mf_open(dbmp, dbmfp, __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_MPOOL *dbmp;
DB_MPOOLFILE *dbmfp; DB_MPOOLFILE *dbmfp;
int ftype, readonly, lsn_offset, istemp; int ftype, lsn_offset, istemp;
size_t pagesize; size_t pagesize;
DBT *pgcookie; DBT *pgcookie;
u_int8_t *fileid; u_int8_t *fileid;
@ -255,13 +274,8 @@ __memp_mf_open(dbmp, dbmfp,
mfp = NULL; mfp = NULL;
goto ret1; goto ret1;
} }
/* /* Found it: increment the reference count. */
* Found it: increment the reference count and update
* the mmap-able status.
*/
++mfp->ref; ++mfp->ref;
if (!readonly)
mfp->can_mmap = 0;
goto ret1; goto ret1;
} }
@ -273,6 +287,7 @@ alloc: if ((ret = __memp_ralloc(dbmp, sizeof(MPOOLFILE), NULL, &mfp)) != 0)
memset(mfp, 0, sizeof(MPOOLFILE)); memset(mfp, 0, sizeof(MPOOLFILE));
mfp->ref = 1; mfp->ref = 1;
mfp->ftype = ftype; mfp->ftype = ftype;
mfp->can_mmap = 1;
mfp->lsn_off = lsn_offset; mfp->lsn_off = lsn_offset;
mfp->stat.st_pagesize = pagesize; mfp->stat.st_pagesize = pagesize;
@ -343,9 +358,9 @@ memp_fclose(dbmfp)
dbmfp->path, (u_long)dbmfp->pinref); dbmfp->path, (u_long)dbmfp->pinref);
/* Remove the DB_MPOOLFILE structure from the list. */ /* Remove the DB_MPOOLFILE structure from the list. */
LOCKHANDLE(dbmp, &dbmp->mutex); LOCKHANDLE(dbmp, dbmp->mutexp);
TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q); TAILQ_REMOVE(&dbmp->dbmfq, dbmfp, q);
UNLOCKHANDLE(dbmp, &dbmp->mutex); UNLOCKHANDLE(dbmp, dbmp->mutexp);
/* Close the underlying MPOOLFILE. */ /* Close the underlying MPOOLFILE. */
(void)__memp_mf_close(dbmp, dbmfp); (void)__memp_mf_close(dbmp, dbmfp);
@ -362,11 +377,16 @@ memp_fclose(dbmfp)
t_ret = ret; t_ret = ret;
} }
/* Potentially allocated path. */ /* Free memory. */
if (F_ISSET(dbmfp, MP_PATH_ALLOC)) if (F_ISSET(dbmfp, MP_PATH_ALLOC))
FREES(dbmfp->path); 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)); FREE(dbmfp, sizeof(DB_MPOOLFILE));
return (ret); return (ret);

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -31,7 +31,7 @@ int
memp_fput(dbmfp, pgaddr, flags) memp_fput(dbmfp, pgaddr, flags)
DB_MPOOLFILE *dbmfp; DB_MPOOLFILE *dbmfp;
void *pgaddr; void *pgaddr;
u_long flags; int flags;
{ {
BH *bhp; BH *bhp;
DB_MPOOL *dbmp; DB_MPOOL *dbmp;
@ -58,14 +58,14 @@ memp_fput(dbmfp, pgaddr, flags)
} }
/* Decrement the pinned reference count. */ /* Decrement the pinned reference count. */
LOCKHANDLE(dbmp, &dbmfp->mutex); LOCKHANDLE(dbmp, dbmfp->mutexp);
if (dbmfp->pinref == 0) if (dbmfp->pinref == 0)
__db_err(dbmp->dbenv, __db_err(dbmp->dbenv,
"%s: put: more blocks returned than retrieved", "%s: put: more blocks returned than retrieved",
dbmfp->path); dbmfp->path);
else else
--dbmfp->pinref; --dbmfp->pinref;
UNLOCKHANDLE(dbmp, &dbmfp->mutex); UNLOCKHANDLE(dbmp, dbmfp->mutexp);
/* /*
* If we're mapping the file, there's nothing to do. Because we can * If we're mapping the file, there's nothing to do. Because we can

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -30,7 +30,7 @@ int
memp_fset(dbmfp, pgaddr, flags) memp_fset(dbmfp, pgaddr, flags)
DB_MPOOLFILE *dbmfp; DB_MPOOLFILE *dbmfp;
void *pgaddr; void *pgaddr;
u_long flags; int flags;
{ {
BH *bhp; BH *bhp;
DB_MPOOL *dbmp; DB_MPOOL *dbmp;

View File

@ -7,7 +7,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -56,7 +56,6 @@ memp_open(path, flags, mode, dbenv, retp)
/* Create and initialize the DB_MPOOL structure. */ /* Create and initialize the DB_MPOOL structure. */
if ((dbmp = (DB_MPOOL *)calloc(1, sizeof(DB_MPOOL))) == NULL) if ((dbmp = (DB_MPOOL *)calloc(1, sizeof(DB_MPOOL))) == NULL)
return (ENOMEM); return (ENOMEM);
LOCKINIT(dbmp, &dbmp->mutex);
LIST_INIT(&dbmp->dbregq); LIST_INIT(&dbmp->dbregq);
TAILQ_INIT(&dbmp->dbmfq); TAILQ_INIT(&dbmp->dbmfq);
@ -67,6 +66,17 @@ memp_open(path, flags, mode, dbenv, retp)
(dbenv != NULL && F_ISSET(dbenv, DB_MPOOL_PRIVATE))) (dbenv != NULL && F_ISSET(dbenv, DB_MPOOL_PRIVATE)))
F_SET(dbmp, MP_ISPRIVATE); 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 * 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). * 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 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 * 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)) if (!F_ISSET(dbmp, MP_ISPRIVATE))
F_SET(dbmp, MP_LOCKREGION); F_SET(dbmp, MP_LOCKREGION);
if (LF_ISSET(DB_THREAD)) if (LF_ISSET(DB_THREAD)) {
F_SET(dbmp, MP_LOCKHANDLE | MP_LOCKREGION); 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; *retp = dbmp;
return (0); return (0);
@ -119,11 +139,18 @@ memp_close(dbmp)
if ((t_ret = memp_fclose(dbmfp)) != 0 && ret == 0) if ((t_ret = memp_fclose(dbmfp)) != 0 && ret == 0)
ret = t_ret; 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. */ /* Close the region. */
if ((t_ret = __memp_rclose(dbmp)) && ret == 0) if ((t_ret = __memp_rclose(dbmp)) && ret == 0)
ret = t_ret; ret = t_ret;
/* Free the structure. */ /* Discard the structure. */
FREE(dbmp, sizeof(DB_MPOOL)); FREE(dbmp, sizeof(DB_MPOOL));
return (ret); return (ret);
@ -168,9 +195,9 @@ memp_register(dbmp, ftype, pgin, pgout)
* the most recent registry in the case of multiple entries, so * the most recent registry in the case of multiple entries, so
* we don't have to check for multiple registries. * we don't have to check for multiple registries.
*/ */
LOCKHANDLE(dbmp, &dbmp->mutex); LOCKHANDLE(dbmp, dbmp->mutexp);
LIST_INSERT_HEAD(&dbmp->dbregq, mpr, q); LIST_INSERT_HEAD(&dbmp->dbregq, mpr, q);
UNLOCKHANDLE(dbmp, &dbmp->mutex); UNLOCKHANDLE(dbmp, dbmp->mutexp);
return (0); return (0);
} }

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES

View File

@ -8,7 +8,7 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -60,9 +60,11 @@ __db_dir(dbenv, dir, namesp, cntp)
struct _finddata_t fdata; struct _finddata_t fdata;
long dirhandle; long dirhandle;
int finished; int finished;
char filespec[MAX_PATH];
if ((dirhandle = _findfirst(dir, &fdata)) == -1) { (void)snprintf(filespec, sizeof(filespec), "%s/*", dir);
__db_err(dbenv, "%s: %s", dir, strerror(errno)); if ((dirhandle = _findfirst(filespec, &fdata)) == -1) {
__db_err(dbenv, "%s: %s", filespec, strerror(errno));
return (errno); return (errno);
} }

View File

@ -11,7 +11,7 @@
static const char copyright[] = static const char copyright[] =
"@(#) Copyright (c) 1997\n\ "@(#) Copyright (c) 1997\n\
Sleepycat Software Inc. All rights reserved.\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 #endif
#ifndef NO_SYSTEM_INCLUDES #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 <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -59,7 +60,7 @@ main(argc, argv)
DB_ENV *dbenv; DB_ENV *dbenv;
time_t now; time_t now;
long kbytes, minutes, seconds; long kbytes, minutes, seconds;
int ch, rval, verbose; int ch, eval, verbose;
char *home, *logfile; char *home, *logfile;
home = logfile = NULL; home = logfile = NULL;
@ -110,7 +111,7 @@ main(argc, argv)
* to wake up when a checkpoint is necessary. If we have a "kbytes" * to wake up when a checkpoint is necessary. If we have a "kbytes"
* field set, then we'll check every 30 seconds. * field set, then we'll check every 30 seconds.
*/ */
rval = 0; eval = 0;
seconds = kbytes != 0 ? 30 : minutes * 60; seconds = kbytes != 0 ? 30 : minutes * 60;
while (!interrupted) { while (!interrupted) {
(void)__db_sleep(seconds, 0); (void)__db_sleep(seconds, 0);
@ -119,23 +120,25 @@ main(argc, argv)
(void)time(&now); (void)time(&now);
printf("checkpoint: %s", ctime(&now)); printf("checkpoint: %s", ctime(&now));
} }
rval = txn_checkpoint(dbenv->tx_info, kbytes, minutes); errno = txn_checkpoint(dbenv->tx_info, kbytes, minutes);
if (rval < 0)
break;
while (rval > 0) { while (errno == DB_INCOMPLETE) {
if (verbose) if (verbose)
__db_err(dbenv, __db_err(dbenv,
"checkpoint did not finish, retrying"); "checkpoint did not finish, retrying");
(void)__db_sleep(2, 0); (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; break;
} }
}
if (logfile != NULL && logpid(logfile, 0)) if (logfile != NULL && logpid(logfile, 0))
rval = 1; eval = 1;
if (interrupted) { if (interrupted) {
(void)signal(interrupted, SIG_DFL); (void)signal(interrupted, SIG_DFL);
@ -143,7 +146,7 @@ main(argc, argv)
/* NOTREACHED */ /* NOTREACHED */
} }
return (db_appexit(dbenv) || rval ? 1 : 0); return (db_appexit(dbenv) || eval ? 1 : 0);
} }
/* /*

View File

@ -11,7 +11,7 @@
static const char copyright[] = static const char copyright[] =
"@(#) Copyright (c) 1997\n\ "@(#) Copyright (c) 1997\n\
Sleepycat Software Inc. All rights reserved.\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 #endif
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES

View File

@ -11,7 +11,7 @@
static const char copyright[] = static const char copyright[] =
"@(#) Copyright (c) 1997\n\ "@(#) Copyright (c) 1997\n\
Sleepycat Software Inc. All rights reserved.\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 #endif
#ifndef NO_SYSTEM_INCLUDES #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_BTREE, NULL)) == NULL) {
if ((dbp = dbopen(argv[0], O_RDONLY, 0, DB_HASH, 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); db_185_hash(dbp, pflag);
} else } else
db_185_btree(dbp, pflag); db_185_btree(dbp, pflag);

View File

@ -11,7 +11,7 @@
static const char copyright[] = static const char copyright[] =
"@(#) Copyright (c) 1997\n\ "@(#) Copyright (c) 1997\n\
Sleepycat Software Inc. All rights reserved.\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 #endif
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -59,7 +59,7 @@ main(argc, argv)
char **clist, **clp, *home; char **clist, **clp, *home;
/* Allocate enough room for configuration arguments. */ /* 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); err(1, NULL);
home = NULL; home = NULL;

View File

@ -11,7 +11,7 @@
static const char copyright[] = static const char copyright[] =
"@(#) Copyright (c) 1997\n\ "@(#) Copyright (c) 1997\n\
Sleepycat Software Inc. All rights reserved.\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 #endif
#ifndef NO_SYSTEM_INCLUDES #ifndef NO_SYSTEM_INCLUDES
@ -24,6 +24,7 @@ static const char sccsid[] = "@(#)db_recover.c 10.14 (Sleepycat) 8/27/97";
#endif #endif
#include "db_int.h" #include "db_int.h"
#include "shqueue.h"
#include "txn.h" #include "txn.h"
#include "common_ext.h" #include "common_ext.h"
#include "clib_ext.h" #include "clib_ext.h"

View File

@ -43,16 +43,10 @@
#include "config.h" #include "config.h"
#ifndef lint #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 */ #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 #ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
@ -87,10 +81,12 @@ static int __txn_undo __P((DB_TXN *));
static int __txn_validate_region __P((DB_TXNMGR *)); 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. * Create and initialize a transaction region in shared memory.
* 0 means, success. * Return 0 on success, errno on failure.
* +1 means that the db_create failed, so we did not create the region.
* -1 means that we got some sort of system error.
*/ */
static int static int
__txn_create(dbenv, path, mode) __txn_create(dbenv, path, mode)
@ -99,9 +95,8 @@ __txn_create(dbenv, path, mode)
u_int mode; u_int mode;
{ {
DB_TXNREGION *txn_region; DB_TXNREGION *txn_region;
TXN_DETAIL *txnp;
time_t now; time_t now;
int fd, i, maxtxns, ret; int fd, maxtxns, ret;
maxtxns = dbenv->tx_max != 0 ? dbenv->tx_max : 1000; maxtxns = dbenv->tx_max != 0 ? dbenv->tx_max : 1000;
(void)time(&now); (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. */ /* XXX If we ever do more types of locking and logging, this changes. */
txn_region->logtype = 0; txn_region->logtype = 0;
txn_region->locktype = 0; txn_region->locktype = 0;
txn_region->free_txn = 0;
txn_region->time_ckp = now; txn_region->time_ckp = now;
ZERO_LSN(txn_region->last_ckp); ZERO_LSN(txn_region->last_ckp);
ZERO_LSN(txn_region->pending_ckp); ZERO_LSN(txn_region->pending_ckp);
SH_TAILQ_INIT(&txn_region->active_txn);
for (txnp = &txn_region->table[0], i = 0; i < maxtxns; i++, txnp++) { __db_shalloc_init((void *)&txn_region[1],
ZERO_LSN(txnp->begin_lsn); TXN_REGION_SIZE(maxtxns) - sizeof(DB_TXNREGION));
txnp->status = TXN_UNALLOC;
txnp->txnid = i + 1;
}
txn_region->table[maxtxns - 1].txnid = TXN_INVALID;
/* Unlock the region. */ /* Unlock the region. */
(void)__db_mutex_unlock(&txn_region->hdr.lock, fd); (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); (void)txn_unlink(path, 1 /* force */, dbenv);
return (ret); return (ret);
} }
return (0); 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. */ /* Now, create the transaction manager structure and set its fields. */
if ((tmgrp = (DB_TXNMGR *)malloc(sizeof(DB_TXNMGR))) == NULL) { 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; ret = ENOMEM;
goto out; 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->reg_size = txn_regionp->hdr.size;
tmgrp->fd = fd; tmgrp->fd = fd;
tmgrp->flags = LF_ISSET(DB_TXN_NOSYNC | DB_THREAD); tmgrp->flags = LF_ISSET(DB_TXN_NOSYNC | DB_THREAD);
tmgrp->mem = &txn_regionp[1];
tmgrp->mutexp = NULL;
TAILQ_INIT(&tmgrp->txn_chain); TAILQ_INIT(&tmgrp->txn_chain);
if (LF_ISSET(DB_THREAD)) if (LF_ISSET(DB_THREAD)) {
__db_mutex_init(&tmgrp->mutex, -1); 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; *mgrpp = tmgrp;
return (0); return (0);
@ -221,8 +219,14 @@ out: if (txn_regionp != NULL)
(void)__db_rclose(dbenv, fd, txn_regionp); (void)__db_rclose(dbenv, fd, txn_regionp);
if (flags & DB_CREATE) if (flags & DB_CREATE)
(void)txn_unlink(path, 1, dbenv); (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); free(tmgrp);
}
return (ret); return (ret);
} }
@ -239,30 +243,20 @@ txn_begin(tmgrp, parent, txnpp)
{ {
TXN_DETAIL *txnp; TXN_DETAIL *txnp;
DB_TXN *retp; DB_TXN *retp;
int id, index, ret; int id, ret;
LOCK_TXNREGION(tmgrp); LOCK_TXNREGION(tmgrp);
if ((ret = __txn_validate_region(tmgrp)) != 0) { if ((ret = __txn_validate_region(tmgrp)) != 0)
UNLOCK_TXNREGION(tmgrp); goto err;
return (ret);
}
/* Remove element from free list. */ /* Allocate a new transaction detail structure. */
if (tmgrp->region->free_txn == TXN_INVALID && if ((ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp)) != 0
(ret = __txn_grow_region(tmgrp)) != 0) { && ret == ENOMEM && (ret = __txn_grow_region(tmgrp)) == 0)
UNLOCK_TXNREGION(tmgrp); ret = __db_shalloc(tmgrp->mem, sizeof(TXN_DETAIL), 0, &txnp);
return (ret);
}
index = tmgrp->region->free_txn; if (ret != 0)
txnp = &tmgrp->region->table[index]; goto err;
tmgrp->region->free_txn = txnp->txnid;
if (txnp->status != TXN_UNALLOC) {
UNLOCK_TXNREGION(tmgrp);
return (EINVAL);
}
/* Make sure that last_txnid is not going to wrap around. */ /* Make sure that last_txnid is not going to wrap around. */
if (tmgrp->region->last_txnid == TXN_INVALID) 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) { if ((retp = (DB_TXN *)malloc(sizeof(DB_TXN))) == NULL) {
__db_err(tmgrp->dbenv, "txn_begin : %s", strerror(ENOMEM)); __db_err(tmgrp->dbenv, "txn_begin : %s", strerror(ENOMEM));
UNLOCK_TXNREGION(tmgrp); ret = ENOMEM;
return (ENOMEM); goto err1;
} }
id = ++tmgrp->region->last_txnid; id = ++tmgrp->region->last_txnid;
tmgrp->region->nbegins++; tmgrp->region->nbegins++;
txnp->txnid = id; txnp->txnid = id;
txnp->last_lock = 0;
txnp->status = TXN_RUNNING;
ZERO_LSN(txnp->last_lsn); ZERO_LSN(txnp->last_lsn);
ZERO_LSN(txnp->begin_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); UNLOCK_TXNREGION(tmgrp);
@ -297,8 +293,9 @@ txn_begin(tmgrp, parent, txnpp)
/* Deallocate transaction. */ /* Deallocate transaction. */
LOCK_TXNREGION(tmgrp); LOCK_TXNREGION(tmgrp);
txnp->txnid = tmgrp->region->free_txn; SH_TAILQ_REMOVE(&tmgrp->region->active_txn,
tmgrp->region->free_txn = txnp - &tmgrp->region->table[0]; txnp, links, __txn_detail);
__db_shalloc_free(tmgrp->mem, txnp);
UNLOCK_TXNREGION(tmgrp); UNLOCK_TXNREGION(tmgrp);
free (retp); free (retp);
return (ret); return (ret);
@ -310,6 +307,12 @@ txn_begin(tmgrp, parent, txnpp)
*txnpp = retp; *txnpp = retp;
return (0); return (0);
err1:
__db_shalloc_free(tmgrp->mem, txnp);
err:
UNLOCK_TXNREGION(tmgrp);
return (ret);
} }
/* The db_txn(3) man page describes txn_commit. */ /* The db_txn(3) man page describes txn_commit. */
@ -362,16 +365,15 @@ txn_prepare(txnp)
int ret; int ret;
TXN_DETAIL *tp; TXN_DETAIL *tp;
ret = 0;
if ((ret = __txn_check_running(txnp)) != 0) if ((ret = __txn_check_running(txnp)) != 0)
return (ret); return (ret);
if (txnp->mgrp->dbenv->lg_info) { if (txnp->mgrp->dbenv->lg_info != NULL) {
ret = log_flush(txnp->mgrp->dbenv->lg_info, &txnp->last_lsn); if ((ret = log_flush(txnp->mgrp->dbenv->lg_info,
if (ret) &txnp->last_lsn)) != 0)
__db_err(txnp->mgrp->dbenv, __db_err(txnp->mgrp->dbenv,
"txn_prepare: log_flush failed %s\n", "txn_prepare: log_flush failed %s\n",
strerror(errno)); strerror(ret));
return (ret); return (ret);
} }
@ -420,12 +422,19 @@ txn_close(tmgrp)
ret == 0) ret == 0)
ret = t_ret; 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 if ((t_ret = __db_rclose(tmgrp->dbenv, tmgrp->fd, tmgrp->region)) != 0
&& ret == 0) && ret == 0)
ret = t_ret; ret = t_ret;
if (ret == 0) if (ret == 0)
free (tmgrp); free (tmgrp);
return (ret); return (ret);
} }
@ -499,9 +508,8 @@ __txn_end(txnp, is_commit)
/* End the transaction. */ /* End the transaction. */
LOCK_TXNREGION(mgr); LOCK_TXNREGION(mgr);
tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + txnp->off); tp = (TXN_DETAIL *)((u_int8_t *)mgr->region + txnp->off);
tp->status = TXN_UNALLOC; SH_TAILQ_REMOVE(&mgr->region->active_txn, tp, links, __txn_detail);
tp->txnid = mgr->region->free_txn; __db_shalloc_free(mgr->mem, tp);
mgr->region->free_txn = tp - &mgr->region->table[0];
if (is_commit) if (is_commit)
mgr->region->ncommits++; mgr->region->ncommits++;
else else
@ -515,8 +523,9 @@ __txn_end(txnp, is_commit)
/* /*
* Undo the transaction with id txnid. Returns 0 on success and sets * __txn_undo --
* errno and returns -1 on failure. * Undo the transaction with id txnid. Returns 0 on success and
* errno on failure.
*/ */
static int static int
__txn_undo(txnp) __txn_undo(txnp)
@ -576,12 +585,12 @@ __txn_undo(txnp)
int int
txn_checkpoint(mgr, kbytes, minutes) txn_checkpoint(mgr, kbytes, minutes)
const DB_TXNMGR *mgr; const DB_TXNMGR *mgr;
long kbytes, minutes; int kbytes, minutes;
{ {
TXN_DETAIL *txnp; TXN_DETAIL *txnp;
DB_LSN ckp_lsn, last_ckp; DB_LSN ckp_lsn, last_ckp;
DB_LOG *dblp; DB_LOG *dblp;
u_int32_t bytes_written, i; u_int32_t bytes_written;
time_t last_ckp_time, now; time_t last_ckp_time, now;
int ret; int ret;
@ -638,16 +647,16 @@ do_ckp:
if (!IS_ZERO_LSN(mgr->region->pending_ckp)) if (!IS_ZERO_LSN(mgr->region->pending_ckp))
ckp_lsn = mgr->region->pending_ckp; ckp_lsn = mgr->region->pending_ckp;
else else
for (txnp = &mgr->region->table[0], i = 0; for (txnp =
i < mgr->region->maxtxns; i++, 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 * Look through the active transactions for the
* the transaction that is in-use (e.g., not * lowest begin lsn.
* TXN_UNALLOC) and whose begin lsn is the lowest.
*/ */
if (txnp->status != TXN_UNALLOC && if (!IS_ZERO_LSN(txnp->begin_lsn) &&
!IS_ZERO_LSN(txnp->begin_lsn) &&
log_compare(&txnp->begin_lsn, &ckp_lsn) < 0) log_compare(&txnp->begin_lsn, &ckp_lsn) < 0)
ckp_lsn = txnp->begin_lsn; ckp_lsn = txnp->begin_lsn;
} }
@ -707,6 +716,7 @@ __txn_validate_region(tp)
return (ret); return (ret);
tp->reg_size = tp->region->hdr.size; tp->reg_size = tp->region->hdr.size;
tp->mem = &tp->region[1];
return (0); return (0);
} }
@ -715,9 +725,9 @@ static int
__txn_grow_region(tp) __txn_grow_region(tp)
DB_TXNMGR *tp; DB_TXNMGR *tp;
{ {
TXN_DETAIL *tx;
size_t incr; size_t incr;
u_int32_t i, oldmax; u_int32_t oldmax;
u_int8_t *curaddr;
int ret; int ret;
oldmax = tp->region->maxtxns; oldmax = tp->region->maxtxns;
@ -729,19 +739,17 @@ __txn_grow_region(tp)
if ((ret = __db_rremap(tp->dbenv, tp->region, if ((ret = __db_rremap(tp->dbenv, tp->region,
tp->reg_size, tp->reg_size + incr, tp->fd, &tp->region)) != 0) tp->reg_size, tp->reg_size + incr, tp->fd, &tp->region)) != 0)
return (ret); 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; tp->reg_size += incr;
/* *((size_t *)curaddr) = incr - sizeof(size_t);
* Initialize all the new transactions and up the transaction count. curaddr += sizeof(size_t);
*/ __db_shalloc_free(tp->mem, curaddr);
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;
tp->region->maxtxns = 2 * oldmax; tp->region->maxtxns = 2 * oldmax;
tp->region->table[tp->region->maxtxns - 1].txnid = TXN_INVALID;
return (0); return (0);
} }
@ -753,8 +761,9 @@ txn_stat(mgr, statp, db_malloc)
void *(*db_malloc) __P((size_t)); void *(*db_malloc) __P((size_t));
{ {
DB_TXN_STAT *stats; DB_TXN_STAT *stats;
TXN_DETAIL *txnp;
size_t nbytes; size_t nbytes;
u_int32_t i, nactive, ndx; u_int32_t nactive, ndx;
LOCK_TXNREGION(mgr); LOCK_TXNREGION(mgr);
nactive = mgr->region->nbegins - nactive = mgr->region->nbegins -
@ -789,12 +798,12 @@ txn_stat(mgr, statp, db_malloc)
stats->st_nactive = nactive + 200; stats->st_nactive = nactive + 200;
stats->st_txnarray = (DB_TXN_ACTIVE *)&stats[1]; stats->st_txnarray = (DB_TXN_ACTIVE *)&stats[1];
for (ndx = 0, i = 0; i < mgr->region->maxtxns; i++) ndx = 0;
if (mgr->region->table[i].status != TXN_UNALLOC) { for (txnp = SH_TAILQ_FIRST(&mgr->region->active_txn, __txn_detail);
stats->st_txnarray[ndx].txnid = txnp != NULL;
mgr->region->table[i].txnid; txnp = SH_TAILQ_NEXT(txnp, links, __txn_detail)) {
stats->st_txnarray[ndx].lsn = stats->st_txnarray[ndx].txnid = txnp->txnid;
mgr->region->table[i].begin_lsn; stats->st_txnarray[ndx].lsn = txnp->begin_lsn;
ndx++; ndx++;
if (ndx >= stats->st_nactive) if (ndx >= stats->st_nactive)

View File

@ -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' /* Structure describing a loaded shared object. The `l_next' and `l_prev'
members form a chain of all the shared objects loaded at startup. 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. /* All following members are internal to the dynamic linker.
They may change without notice. */ They may change without notice. */
struct libname_list struct libname_list *l_libname;
{
const char *name; /* Name requested (before search). */
struct libname_list *next; /* Link to next name for this object. */
} *l_libname;
/* Indexed pointers to dynamic section. /* Indexed pointers to dynamic section.
[0,DT_NUM) are indexed by the processor-independent tags. [0,DT_NUM) are indexed by the processor-independent tags.
[DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC. [DT_NUM,DT_NUM+DT_PROCNUM) are indexed by the tag minus DT_LOPROC.

View File

@ -13,7 +13,7 @@ static void (*const __DTOR_END__[1]) (void)
this would be the 'length' field in a real FDE. */ this would be the 'length' field in a real FDE. */
typedef unsigned int ui32 __attribute__ ((mode (SI))); typedef unsigned int ui32 __attribute__ ((mode (SI)));
static const ui32 __FRAME_END__[1] static ui32 __FRAME_END__[1]
__attribute__ ((unused, section (".eh_frame"))) __attribute__ ((unused, section (".eh_frame")))
= { 0 }; = { 0 };
#endif #endif

View File

@ -18,7 +18,7 @@ run_hooks (void (*const list[]) (void))
} }
#ifdef HAVE_DWARF2_UNWIND_INFO #ifdef HAVE_DWARF2_UNWIND_INFO
static const char __EH_FRAME_BEGIN__[] static char __EH_FRAME_BEGIN__[]
__attribute__ ((section (".eh_frame"))) __attribute__ ((section (".eh_frame")))
= { }; = { };
extern void __register_frame (const void *); extern void __register_frame (const void *);

View File

@ -27,7 +27,8 @@
_POSIX_SOURCE IEEE Std 1003.1. _POSIX_SOURCE IEEE Std 1003.1.
_POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2; _POSIX_C_SOURCE If ==1, like _POSIX_SOURCE; if >=2 add IEEE Std 1003.2;
if >=199309L, add IEEE Std 1003.1b-1993 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. _XOPEN_SOURCE_EXTENDED XPG things and X/Open Unix extensions.
_BSD_SOURCE ISO C, POSIX, and 4.3BSD things. _BSD_SOURCE ISO C, POSIX, and 4.3BSD things.
_SVID_SOURCE ISO C, POSIX, and SVID things. _SVID_SOURCE ISO C, POSIX, and SVID things.
@ -50,6 +51,7 @@
__USE_POSIX199309 Define IEEE Std 1003.1b things. __USE_POSIX199309 Define IEEE Std 1003.1b things.
__USE_XOPEN Define XPG things. __USE_XOPEN Define XPG things.
__USE_XOPEN_EXTENDED Define X/Open Unix things. __USE_XOPEN_EXTENDED Define X/Open Unix things.
__USE_UNIX98 Define Single Unix V2 things.
__USE_BSD Define 4.3BSD things. __USE_BSD Define 4.3BSD things.
__USE_SVID Define SVID things. __USE_SVID Define SVID things.
__USE_MISC Define things common to BSD and System V Unix. __USE_MISC Define things common to BSD and System V Unix.
@ -111,7 +113,7 @@
# undef _POSIX_C_SOURCE # undef _POSIX_C_SOURCE
# define _POSIX_C_SOURCE 199309L # define _POSIX_C_SOURCE 199309L
# undef _XOPEN_SOURCE # undef _XOPEN_SOURCE
# define _XOPEN_SOURCE 1 # define _XOPEN_SOURCE 500
# undef _XOPEN_SOURCE_EXTENDED # undef _XOPEN_SOURCE_EXTENDED
# define _XOPEN_SOURCE_EXTENDED 1 # define _XOPEN_SOURCE_EXTENDED 1
# undef _BSD_SOURCE # undef _BSD_SOURCE
@ -141,7 +143,7 @@
#if (!defined __STRICT_ANSI__ && !defined _POSIX_SOURCE && \ #if (!defined __STRICT_ANSI__ && !defined _POSIX_SOURCE && \
!defined _POSIX_C_SOURCE) !defined _POSIX_C_SOURCE)
# define _POSIX_SOURCE 1 # define _POSIX_SOURCE 1
# ifdef _XOPEN_SOURCE # if defined _XOPEN_SOURCE && _XOPEN_SOURCE != 500
# define _POSIX_C_SOURCE 2 # define _POSIX_C_SOURCE 2
# else # else
# define _POSIX_C_SOURCE 199309L # define _POSIX_C_SOURCE 199309L
@ -162,10 +164,15 @@
#ifdef _XOPEN_SOURCE #ifdef _XOPEN_SOURCE
# define __USE_XOPEN 1 # define __USE_XOPEN 1
# if _XOPEN_SOURCE == 500
# define __USE_XOPEN_EXTENDED 1
# define __USE_UNIX98 1
# else
# ifdef _XOPEN_SOURCE_EXTENDED # ifdef _XOPEN_SOURCE_EXTENDED
# define __USE_XOPEN_EXTENDED 1 # define __USE_XOPEN_EXTENDED 1
# endif # endif
# endif # endif
#endif
#if defined _BSD_SOURCE || defined _SVID_SOURCE #if defined _BSD_SOURCE || defined _SVID_SOURCE
# define __USE_MISC 1 # define __USE_MISC 1

View File

@ -597,3 +597,28 @@ stpcpy (dest, src)
return dest - 1; return dest - 1;
} }
#endif #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

View File

@ -197,3 +197,23 @@ _nl_find_domain (dirname, locale, domainname)
return retval; 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

View File

@ -50,6 +50,8 @@ SWAP (i)
struct loaded_domain struct loaded_domain
{ {
const char *data; const char *data;
int use_mmap;
size_t mmap_size;
int must_swap; int must_swap;
nls_uint32 nstrings; nls_uint32 nstrings;
struct string_desc *orig_tab; struct string_desc *orig_tab;
@ -69,6 +71,7 @@ struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
char *__locale, char *__locale,
const char *__domainname)); const char *__domainname));
void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain)); void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
void _nl_unload_domain PARAMS ((struct loaded_domain *__domain));
/* @@ begin of epilog @@ */ /* @@ begin of epilog @@ */

View File

@ -168,6 +168,8 @@ _nl_load_domain (domain_file)
domain = (struct loaded_domain *) domain_file->data; domain = (struct loaded_domain *) domain_file->data;
domain->data = (char *) data; domain->data = (char *) data;
domain->use_mmap = use_mmap;
domain->mmap_size = st.st_size;
domain->must_swap = data->magic != _MAGIC; domain->must_swap = data->magic != _MAGIC;
/* Fill in the information about the available tables. */ /* Fill in the information about the available tables. */
@ -201,3 +203,18 @@ _nl_load_domain (domain_file)
translations invalid. */ translations invalid. */
++_nl_msg_cat_cntr; ++_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

View File

@ -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 struct alias_map *map;
static size_t nmap = 0; static size_t nmap = 0;
static size_t maxmap = 0; static size_t maxmap = 0;
@ -272,7 +275,8 @@ read_alias_file (fname, fname_len)
if (cp[0] != '\0') if (cp[0] != '\0')
{ {
char *tp; char *tp;
size_t len; size_t alias_len;
size_t value_len;
value = cp++; value = cp++;
while (cp[0] != '\0' && !isspace (cp[0])) while (cp[0] != '\0' && !isspace (cp[0]))
@ -292,35 +296,32 @@ read_alias_file (fname, fname_len)
if (nmap >= maxmap) if (nmap >= maxmap)
extend_alias_table (); extend_alias_table ();
#if defined _LIBC || defined HAVE_STRDUP alias_len = strlen (alias) + 1;
map[nmap].alias = strdup (alias); value_len = strlen (value) + 1;
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;
len = strlen (value) + 1; if (string_space_act + alias_len + value_len > string_space_max)
tp = (char *) malloc (len); {
if (tp == NULL) /* 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); FREE_BLOCKS (block_list);
return added; return added;
} }
memcpy (tp, value, len); string_space = new_pool;
map[nmap].value = tp; string_space_max = new_size;
#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; ++nmap;
++added; ++added;
@ -359,22 +360,30 @@ extend_alias_table ()
struct alias_map *new_map; struct alias_map *new_map;
new_size = maxmap == 0 ? 100 : 2 * maxmap; new_size = maxmap == 0 ? 100 : 2 * maxmap;
new_map = (struct alias_map *) malloc (new_size new_map = (struct alias_map *) realloc (map, (new_size
* sizeof (struct alias_map)); * sizeof (struct alias_map)));
if (new_map == NULL) if (new_map == NULL)
/* Simply don't extend: we don't have any more core. */ /* Simply don't extend: we don't have any more core. */
return; return;
memcpy (new_map, map, nmap * sizeof (struct alias_map));
if (maxmap != 0)
free (map);
map = new_map; map = new_map;
maxmap = new_size; 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 static int
alias_compare (map1, map2) alias_compare (map1, map2)
const struct alias_map *map1; const struct alias_map *map1;

View File

@ -177,9 +177,9 @@ GLIBC_2.0 {
fgetspent; fgetspent_r; fileno; fileno_unlocked; finite; finitef; fgetspent; fgetspent_r; fileno; fileno_unlocked; finite; finitef;
finitel; flock; flockfile; fmtmsg; fnmatch; fopen; fopencookie; fork; finitel; flock; flockfile; fmtmsg; fnmatch; fopen; fopencookie; fork;
fpathconf; fprintf; fputc; fputc_unlocked; fputs; fread; free; fpathconf; fprintf; fputc; fputc_unlocked; fputs; fread; free;
freeaddrinfo; freopen; frexp; frexpf; frexpl; fscanf; fseek; fsetpos; freeaddrinfo; freopen; frexp; frexpf; frexpl; fscanf; fseek; fseeko;
fstatfs; fsync; ftell; ftime; ftok; ftruncate; ftrylockfile; fsetpos; fstatfs; fsync; ftell; ftello; ftime; ftok; ftruncate;
fts_children; fts_close; fts_open; fts_read; fts_set; ftw; ftrylockfile; fts_children; fts_close; fts_open; fts_read; fts_set; ftw;
funlockfile; fwrite; funlockfile; fwrite;
# g* # g*
@ -276,8 +276,8 @@ GLIBC_2.0 {
parse_printf_format; passwd2des; pathconf; pause; pciconfig_read; parse_printf_format; passwd2des; pathconf; pause; pciconfig_read;
pciconfig_write; pclose; perror; pciconfig_write; pclose; perror;
personality; pipe; pmap_getmaps; pmap_getport; pmap_rmtcall; pmap_set; personality; pipe; pmap_getmaps; pmap_getport; pmap_rmtcall; pmap_set;
pmap_unset; poll; popen; printf; printf_size; printf_size_info; pmap_unset; poll; popen; pread; printf; printf_size; printf_size_info;
profil; profil_counter; pselect; psignal; profil; profil_counter; pwrite; pselect; psignal;
pthread_attr_destroy; pthread_attr_destroy;
pthread_attr_getdetachstate; pthread_attr_getinheritsched; pthread_attr_getdetachstate; pthread_attr_getinheritsched;

View File

@ -32,7 +32,7 @@ routines := \
\ \
clearerr feof ferror fgetc fileno fputc freopen fseek getc getchar \ clearerr feof ferror fgetc fileno fputc freopen fseek getc getchar \
memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \ memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \
iovdprintf vscanf vsnprintf obprintf fcloseall \ iovdprintf vscanf vsnprintf obprintf fcloseall fseeko ftello \
\ \
libc_fatal libc_fatal

42
libio/fseeko.c Normal file
View File

@ -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;
}

50
libio/ftello.c Normal file
View File

@ -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);
}

View File

@ -496,6 +496,17 @@ extern long int ftell __P ((FILE *__stream));
/* Rewind to the beginning of STREAM. */ /* Rewind to the beginning of STREAM. */
extern void rewind __P ((FILE *__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. */ /* Get STREAM's position. */
extern int fgetpos __P ((FILE *__restrict __stream, extern int fgetpos __P ((FILE *__restrict __stream,
fpos_t *__restrict __pos)); fpos_t *__restrict __pos));

View File

@ -147,7 +147,7 @@ const struct locale_data _nl_C_LC_COLLATE =
{ {
_nl_C_name, _nl_C_name,
NULL, 0, 0, /* no file mapped */ NULL, 0, 0, /* no file mapped */
MAX_USAGE_COUNT, UNDELETABLE,
21, 21,
{ {
{ word: 0 }, { word: 0 },

View File

@ -342,7 +342,7 @@ const struct locale_data _nl_C_LC_CTYPE =
{ {
_nl_C_name, _nl_C_name,
NULL, 0, 0, /* no file mapped */ NULL, 0, 0, /* no file mapped */
MAX_USAGE_COUNT, UNDELETABLE,
15, 15,
{ {
{ string: _nl_C_LC_CTYPE_class }, { string: _nl_C_LC_CTYPE_class },

View File

@ -28,7 +28,7 @@ const struct locale_data _nl_C_LC_MESSAGES =
{ {
_nl_C_name, _nl_C_name,
NULL, 0, 0, /* no file mapped */ NULL, 0, 0, /* no file mapped */
MAX_USAGE_COUNT, UNDELETABLE,
4, 4,
{ {
{ string: "^[yY]" }, { string: "^[yY]" },

View File

@ -31,7 +31,7 @@ const struct locale_data _nl_C_LC_MONETARY =
{ {
_nl_C_name, _nl_C_name,
NULL, 0, 0, /* no file mapped */ NULL, 0, 0, /* no file mapped */
MAX_USAGE_COUNT, UNDELETABLE,
15, 15,
{ {
{ string: "" }, { string: "" },

View File

@ -31,7 +31,7 @@ const struct locale_data _nl_C_LC_NUMERIC =
{ {
_nl_C_name, _nl_C_name,
NULL, 0, 0, /* no file mapped */ NULL, 0, 0, /* no file mapped */
MAX_USAGE_COUNT, UNDELETABLE,
3, 3,
{ {
{ string: "." }, { string: "." },

View File

@ -26,7 +26,7 @@ const struct locale_data _nl_C_LC_TIME =
{ {
_nl_C_name, _nl_C_name,
NULL, 0, 0, /* no file mapped */ NULL, 0, 0, /* no file mapped */
MAX_USAGE_COUNT, UNDELETABLE,
54, 54,
{ {
{ string: "Sun" }, { string: "Sun" },

View File

@ -176,7 +176,7 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
/* Increment the usage count. */ /* Increment the usage count. */
if (((struct locale_data *) locale_file->data)->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; ++((struct locale_data *) locale_file->data)->usage_count;
return (struct locale_data *) locale_file->data; return (struct locale_data *) locale_file->data;
@ -213,7 +213,7 @@ _nl_remove_locale (int locale, struct locale_data *data)
permanent. */ permanent. */
if (__munmap ((caddr_t) data->filedata, data->filesize) != 0) if (__munmap ((caddr_t) data->filedata, data->filesize) != 0)
{ {
data->usage_count = MAX_USAGE_COUNT; data->usage_count = UNDELETABLE;
return; return;
} }
} }
@ -225,3 +225,26 @@ _nl_remove_locale (int locale, struct locale_data *data)
free (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);

View File

@ -221,3 +221,14 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
__close (fd); __close (fd);
file->data = newdata; 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);
}

View File

@ -38,7 +38,8 @@
/* We use a special value for the usage counter in `locale_data' to /* We use a special value for the usage counter in `locale_data' to
signal that this data must never be removed anymore. */ 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. */ /* Structure describing locale data in core for a category. */
struct locale_data 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. */ /* Try to load the file described by FILE. */
extern void _nl_load_locale (struct loaded_l10nfile *file, int category); 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. */ /* 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); extern void _nl_remove_locale (int locale, struct locale_data *data);

View File

@ -108,7 +108,7 @@ static const struct argp_option options[] =
{ "posix", OPT_POSIX, NULL, 0, N_("Be strictly POSIX conform") }, { "posix", OPT_POSIX, NULL, 0, N_("Be strictly POSIX conform") },
{ "quiet", OPT_QUIET, NULL, 0, { "quiet", OPT_QUIET, NULL, 0,
N_("Suppress warnings and information messages") }, 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 } { NULL, 0, NULL, 0, NULL }
}; };

View File

@ -41,6 +41,9 @@ non-lib.a := libmcheck.a
# These should be removed by `make clean'. # These should be removed by `make clean'.
extra-objs = mcheck-init.o libmcheck.a 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. # The AWK script to analyze the output of the mtrace functions.
ifneq ($(PERL),no) ifneq ($(PERL),no)
install-bin = mtrace install-bin = mtrace

View File

@ -193,6 +193,23 @@ tr_reallochook (ptr, size, caller)
return hdr; 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 /* We enable tracing if either the environment variable MALLOC_TRACE
is set, or if the variable mallwatch has been patched to an address 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, that the debugging user wants us to stop on. When patching mallwatch,
@ -201,6 +218,9 @@ tr_reallochook (ptr, size, caller)
void void
mtrace () mtrace ()
{ {
#ifdef _LIBC
static int added_atexit_handler = 0;
#endif
char *mallfile; char *mallfile;
/* Don't panic if we're called more than once. */ /* Don't panic if we're called more than once. */
@ -229,6 +249,13 @@ mtrace ()
__malloc_hook = tr_mallochook; __malloc_hook = tr_mallochook;
tr_old_realloc_hook = __realloc_hook; tr_old_realloc_hook = __realloc_hook;
__realloc_hook = tr_reallochook; __realloc_hook = tr_reallochook;
#ifdef _LIBC
if (!added_atexit_handler)
{
added_atexit_handler = 1;
atexit (release_libc_mem);
}
#endif
} }
} }
} }

33
malloc/set-freeres.c Normal file
View File

@ -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, ());
}

View File

@ -85,6 +85,10 @@ BSD and SVID is also included.
If the macro @code{_XOPEN_SOURCE_EXTENDED} is also defined, even more If the macro @code{_XOPEN_SOURCE_EXTENDED} is also defined, even more
functionality is available. The extra functions will make all functions functionality is available. The extra functions will make all functions
available which are necessary for the X/Open Unix brand. 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 @end defvr
@comment (none) @comment (none)

View File

@ -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}. functions that read from streams, such as @code{fgetc}.
@end deftypefun @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 @cindex writing to a file descriptor
@comment unistd.h @comment unistd.h
@comment POSIX.1 @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 your data has been permanently stored before continuing. (It is more
efficient for the system to batch up consecutive writes and do them all 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 at once when convenient. Normally they will always be written to disk
within a minute or less.) within a minute or less.) Modern systems provide another function
@c !!! xref fsync @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 You can use the @code{O_FSYNC} open mode to make @code{write} always
store the data to disk before returning; @pxref{Operating Modes}. 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}. functions that write to streams, such as @code{fputc}.
@end deftypefun @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 @node File Position Primitive
@section Setting the File Position of a Descriptor @section Setting the File Position of a Descriptor

View File

@ -697,8 +697,9 @@ order that they were pushed.
Pushing back characters doesn't alter the file; only the internal Pushing back characters doesn't alter the file; only the internal
buffering for the stream is affected. If a file positioning function buffering for the stream is affected. If a file positioning function
(such as @code{fseek} or @code{rewind}; @pxref{File Positioning}) is (such as @code{fseek}, @code{fseeko} or @code{rewind}; @pxref{File
called, any pending pushed-back characters are discarded. Positioning}) is called, any pending pushed-back characters are
discarded.
Unreading a character on a stream that is at end of file clears the 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 end-of-file indicator for the stream, because it makes the character of
@ -3032,6 +3033,28 @@ possibly for other reasons as well. If a failure occurs, a value of
@code{-1} is returned. @code{-1} is returned.
@end deftypefun @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 stdio.h
@comment ISO @comment ISO
@deftypefun int fseek (FILE *@var{stream}, long int @var{offset}, int @var{whence}) @deftypefun int fseek (FILE *@var{stream}, long int @var{offset}, int @var{whence})
@ -3051,9 +3074,28 @@ position or else remembers it so it will be written later in its proper
place in the file. place in the file.
@end deftypefun @end deftypefun
@strong{Portability Note:} In non-POSIX systems, @code{ftell} and @comment stdio.h
@code{fseek} might work reliably only on binary streams. @xref{Binary @comment Unix98
Streams}. @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} The following symbolic constants are defined for use as the @var{whence}
argument to @code{fseek}. They are also used with the @code{lseek} 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 @comment ISO
@deftypevr Macro int SEEK_SET @deftypevr Macro int SEEK_SET
This is an integer constant which, when used as the @var{whence} This is an integer constant which, when used as the @var{whence}
argument to the @code{fseek} function, specifies that the offset argument to the @code{fseek} or @code{fseeko} function, specifies that
provided is relative to the beginning of the file. the offset provided is relative to the beginning of the file.
@end deftypevr @end deftypevr
@comment stdio.h @comment stdio.h
@comment ISO @comment ISO
@deftypevr Macro int SEEK_CUR @deftypevr Macro int SEEK_CUR
This is an integer constant which, when used as the @var{whence} This is an integer constant which, when used as the @var{whence}
argument to the @code{fseek} function, specifies that the offset argument to the @code{fseek} or @code{fseeko} function, specifies that
provided is relative to the current file position. the offset provided is relative to the current file position.
@end deftypevr @end deftypevr
@comment stdio.h @comment stdio.h
@comment ISO @comment ISO
@deftypevr Macro int SEEK_END @deftypevr Macro int SEEK_END
This is an integer constant which, when used as the @var{whence} This is an integer constant which, when used as the @var{whence}
argument to the @code{fseek} function, specifies that the offset argument to the @code{fseek} or @code{fseeko} function, specifies that
provided is relative to the end of the file. the offset provided is relative to the end of the file.
@end deftypevr @end deftypevr
@comment stdio.h @comment stdio.h
@comment ISO @comment ISO
@deftypefun void rewind (FILE *@var{stream}) @deftypefun void rewind (FILE *@var{stream})
The @code{rewind} function positions the stream @var{stream} at the The @code{rewind} function positions the stream @var{stream} at the
begining of the file. It is equivalent to calling @code{fseek} on the begining of the file. It is equivalent to calling @code{fseek} or
@var{stream} with an @var{offset} argument of @code{0L} and a @code{fseeko} on the @var{stream} with an @var{offset} argument of
@var{whence} argument of @code{SEEK_SET}, except that the return @code{0L} and a @var{whence} argument of @code{SEEK_SET}, except that
value is discarded and the error indicator for the stream is reset. the return value is discarded and the error indicator for the stream is
reset.
@end deftypefun @end deftypefun
These three aliases for the @samp{SEEK_@dots{}} constants exist for the 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 @section Portable File-Position Functions
On the GNU system, the file position is truly a character count. You 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 can specify any character count value as an argument to @code{fseek} or
get reliable results for any random access file. However, some @w{ISO C} @code{fseeko} and get reliable results for any random access file.
systems do not represent file positions in this way. 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 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 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 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 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 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 @var{offset} argument to @code{fseek} or @code{fseeko} to move back to
position. the same file position.
@item @item
In a call to @code{fseek} on a text stream, either the @var{offset} must In a call to @code{fseek} or @code{fseeko} on a text stream, either the
either be zero; or @var{whence} must be @code{SEEK_SET} and the @var{offset} must either be zero; or @var{whence} must be
@var{offset} must be the result of an earlier call to @code{ftell} on @code{SEEK_SET} and the @var{offset} must be the result of an earlier
the same stream. call to @code{ftell} on the same stream.
@item @item
The value of the file position indicator of a text stream is undefined 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 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 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 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 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 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 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}. 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 You can move the stream's file position with @code{fseek} or
Positioning}). Moving the file position past the end of the data @code{fseeko} (@pxref{File Positioning}). Moving the file position past
already written fills the intervening space with zeroes. the end of the data already written fills the intervening space with
zeroes.
@end deftypefun @end deftypefun
Here is an example of using @code{open_memstream}: 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 object to match the amount of data that has been written. After a call
to @code{fflush}, you can examine the object temporarily. to @code{fflush}, you can examine the object temporarily.
You can move the file position of an obstack stream with @code{fseek} You can move the file position of an obstack stream with @code{fseek} or
(@pxref{File Positioning}). Moving the file position past the end of @code{fseeko} (@pxref{File Positioning}). Moving the file position past
the data written fills the intervening space with zeros. the end of the data written fills the intervening space with zeros.
To make the object permanent, update the obstack with @code{fflush}, and 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. then use @code{obstack_finish} to finalize the object and get its address.
@ -3691,9 +3740,9 @@ discarded.
@item cookie_seek_function_t *seek @item cookie_seek_function_t *seek
This is the function that performs the equivalent of file positioning on 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 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 to @code{fseek} or @code{fseeko} on this stream can only seek to
buffer; any attempt to seek outside the buffer will return an locations within the buffer; any attempt to seek outside the buffer will
@code{ESPIPE} error. return an @code{ESPIPE} error.
@item cookie_close_function_t *close @item cookie_close_function_t *close
This function performs any appropriate cleanup on the cookie when This function performs any appropriate cleanup on the cookie when

View File

@ -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> Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -50,3 +50,7 @@ hdestroy ()
{ {
hdestroy_r (&htab); hdestroy_r (&htab);
} }
/* Make sure the table is freed if we want to free everything before
exiting. */
text_set_element (__libc_subfreeres, hdestroy);

Some files were not shown because too many files have changed in this diff Show More