Compare commits

...
Author SHA1 Message Date
Miles Bader 45667a533a *** empty log message ***
Tue Mar  5 18:45:14 1996  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/select.c (__select): Include LASTFD in the
	final loop.
1996-03-05 23:48:15 +00:00
Miles Bader 5ac0712ca5 (__select): Include LASTFD in the final loop. 1996-03-05 23:46:23 +00:00
Richard Kenner b49d86bd21 Add -apple and -aux. 1996-03-05 23:34:58 +00:00
Roland McGrath f7eac6eb50 Mon Mar 4 20:54:40 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* Makeconfig ($(common-objpfx)config.make): Depend on config.h.in.


Mon Mar  4 17:35:09 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* hurd/catch-signal.c (hurd_safe_memmove): New function.
	(hurd_safe_copyin, hurd_safe_copyout): New functions.
	* hurd/hurd/sigpreempt.h: Declare them.

Sun Mar  3 08:43:44 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	Replace math code with fdlibm from Sun as modified for netbsd by
	JT Conklin and Ian Taylor, including x86 FPU support.
	* sysdeps/libm-ieee754, sysdeps/libm-i387: New directories.
	* math/math_private.h: New file.
	* sysdeps/i386/fpu/Implies: New file.
	* sysdeps/ieee754/Implies: New file.
	* math/machine/asm.h, math/machine/endian.h: New files.
	* math/Makefile, math/math.h: Rewritten.
	* mathcalls.h, math/mathcalls.h: New file, broken out of math.h.
	* math/finite.c: File removed.
	* sysdeps/generic/Makefile [$(subdir)=math]: Frobnication removed.

	* math/test-math.c: Include errno.h and string.h.

	* sysdeps/unix/bsd/dirstream.h: File removed.
	* sysdeps/unix/bsd/readdir.c: File removed.
1996-03-05 21:41:30 +00:00
Roland McGrath 1521668f2a Sun Mar 3 08:43:44 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* math/test-math.c: Include errno.h and string.h.
1996-03-05 19:06:19 +00:00
Miles Bader 5d8a006d2c A bug fix for the previous select bug fix.
Tue Mar  5 12:14:57 1996  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/select.c (__select): Also don't fault just
	because some fdmask is 0.
1996-03-05 17:35:49 +00:00
Miles Bader 3cf11a4b33 (__select): Don't fault when some fdmask is 0. 1996-03-05 17:15:44 +00:00
Roland McGrath d43e047895 Mon Mar 4 20:54:40 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* Makeconfig ($(common-objpfx)config.make): Depend on config.h.in.
1996-03-05 16:23:22 +00:00
Erik Sandberg 9a0d30bdb1 (moss): Fix previous change. 1996-03-05 03:02:45 +00:00
Miles Bader e9ef1cf37a (__select): Don't increment GOT only because READ/WRITE/EXCEPTFDS is 0! Don't return without frobbing the bitmasks after a timeout. When clearing the bitmasks, only loop from FIRSTFD to LASTFD. 1996-03-05 00:07:01 +00:00
Richard Kenner bba51ac77a Accept -moss* as op sys. 1996-03-04 23:03:15 +00:00
Miles Bader e49639955f Hurd select fixes.
Mon Mar  4 17:35:35 1996  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/select.c (__select):
	Don't increment GOT only because READ/WRITE/EXCEPTFDS is 0!
	Don't return without frobbing the bitmasks after a timeout.
	When clearing the bitmasks, only loop from FIRSTFD to LASTFD.
1996-03-04 22:56:09 +00:00
Roland McGrath c3d3967cd2 Mon Mar 4 17:35:09 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* hurd/catch-signal.c (hurd_safe_memmove): New function.
	(hurd_safe_copyin, hurd_safe_copyout): New functions.
	* hurd/hurd/sigpreempt.h: Declare them.
1996-03-04 22:45:04 +00:00
Roland McGrath 661fa17673 Sat Mar 2 16:35:40 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/m68k/profil-counter.h: File removed.
	* sysdeps/unix/sysv/sysv4/solaris2/sparc/profil-counter.h: File
	removed.
	* sysdeps/generic/profil-counter.h: New file.
1996-03-02 21:38:05 +00:00
Roland McGrath 36ff88f69e Sat Mar 2 16:35:40 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/m68k/profil-counter.h: File removed.
	* sysdeps/unix/sysv/sysv4/solaris2/sparc/profil-counter.h: File
	removed.
	* sysdeps/generic/profil-counter.h: New file.
1996-03-02 21:37:50 +00:00
Brendan Kehoe 48a65a2993 * sysdeps/unix/sysv/sysv4/solaris2/sparc/sigcontext.h: New file,
including <sysdeps/unix/bsd/sun/sparc/sigcontext.h>. 
* sysdeps/unix/sysv/sysv4/solaris2/sparc/profil-counter.h: New file, 
same as linux/m68k/profil-counter.h except the comment.
Fri Mar  1 17:11:59 1996  Brendan Kehoe  <brendan@zen.org>

	* sysdeps/unix/sysv/sysv4/solaris2/sparc/sigcontext.h: New file,
	including <sysdeps/unix/bsd/sun/sparc/sigcontext.h>.
	* sysdeps/unix/sysv/sysv4/solaris2/sparc/profil-counter.h: New file,
	same as linux/m68k/profil-counter.h except the comment.
1996-03-02 01:34:50 +00:00
Roland McGrath 6b628d3634 * stdlib/Makefile (mpn-stuff): New target.
(copy-mpn): Use it.

	* Code copied from GMP updated to 1.937 version.
	* stdlib/strtod.c (HAVE_ALLOCA): Define this for gmp headers.
1996-03-01 18:45:35 +00:00
Roland McGrath bc47d7a85b Regenerated
Fri Mar  1 10:09:46 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* posix/glob.c: Use canonical code from autoconf manual for dirent
 	include.
	[_D_NAMLEN]: Redefine NAMLEN using this.
	(glob_in_dir): Use NAMLEN macro.
1996-03-01 17:42:49 +00:00
Roland McGrath e9607dbeb9 Fri Mar 1 10:09:46 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* posix/glob.c: Use canonical code from autoconf manual for dirent
 	include.
	[_D_NAMLEN]: Redefine NAMLEN using this.
	(glob_in_dir): Use NAMLEN macro.

	* sysdeps/posix/profil.c: New file.

Thu Feb 29 20:55:57 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/m68k/profil-counter.h: New file.

	* libc-symbols.h [GCC >= 2.8] (strong_alias, weak_alias): Remove
	`extern' keyword.

	* time/zic.c, time/zdump.c, time/private.h: Updated from ADO 96e.
1996-03-01 17:40:28 +00:00
Roland McGrath 4a9af5c708 Regenerated
Fri Jan 19 13:28:59 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* posix/glob.c (glob): Use prototype in getlogin decl.

Thu Jan 18 00:32:43 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* posix/glob.c (_GNU_SOURCE): Define if undefined, so glob.h
	defines GNU extensions.
	* posix/fnmatch.c: Likewise.

Fri Jan 12 13:40:01 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* posix/glob.c (glob): Add parens in glob call flags arg for
	GLOB_BRACE case.
1996-03-01 17:07:03 +00:00
Roland McGrath 01fec49ca6 Recognize cpu-vendor [ctj]90-cray, default c90-cray-unicos. From tege. 1996-03-01 14:57:49 +00:00
Miles Bader d1c57d0c40 Updated from ../gpl2lgpl.sed /home/gd/gnu/lib/getopt.c 1996-02-29 01:05:13 +00:00
Roland McGrath b7459e56bd Tue Feb 27 12:14:59 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* time/strftime.c: Support - and _ flags to affect number padding.

	* sysdeps/unix/common/tcsendbrk.c: New file.
1996-02-27 19:19:12 +00:00
Roland McGrath 92777700d2 Mon Feb 26 10:22:30 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/dirstream.h: Rewritten.
	* sysdeps/unix/readdir.c: Rewritten.
	* sysdeps/unix/telldir.c: Rewritten.
	* sysdeps/unix/closedir.c: Use <...> instead of "..." for dirstream.h.
	Remove __ from DIR struct member names.
	* sysdeps/unix/dirfd.c: Likewise.
	* sysdeps/unix/seekdir.c: Likewise.
	* sysdeps/unix/rewinddir.c: Likewise.
	* sysdeps/unix/opendir.c: Likewise.  Don't allocate extra space after
	DIR structure.
	* sysdeps/stub/direct.h: File removed.
	* sysdeps/unix/bsd/bsd4.4/direct.h: File removed.
	* sysdeps/unix/bsd/direct.h: File removed.
	* sysdeps/unix/common/direct.h: File removed.
	* sysdeps/unix/sysv/irix4/direct.h: File removed.
	* sysdeps/unix/sysv/isc3/direct.h: File removed.
	* sysdeps/unix/sysv/sco3.2.4/direct.h: File removed.
	* sysdeps/unix/sysv/sysv4/solaris2/direct.h: File removed.
	* sysdeps/unix/common/direntry.h: New file.
	* sysdeps/unix/bsd/direntry.h: New file.
	* sysdeps/unix/bsd/bsd4.4/direntry.h: New file.
	* sysdeps/unix/sysv/direntry.h: New file.
	* sysdeps/stub/direntry.h: New file.
	* dirent/dirent.h (struct dirent): Type removed.  Include <direntry.h>
	to define it.
	(_D_EXACT_NAMLEN, _D_ALLOC_NAMLEN): New macros.
	* dirent/Makefile (headers): Add direntry.h.
	(distribute): Remove direct.h.
	* sysdeps/posix/getcwd.c: Use new macros instead of d_namlen.
	* dirent/scandir.c: Likewise.
	* io/fts.c (fts_build): Likewise.
	* io/ftw.c (ftw_dir): Likewise.
	* sysdeps/posix/ttyname.c: Likewise.

	* sysdeps/unix/sysv/sysv4/solaris2/syscalls.list: New file.

	* sysdeps/mach/hurd/profil.c (MAX_PC_SAMPLES): New macro.
	(collector_timeout): New static variable.
	(update_waiter): Actually call __task_enable_pc_sampling.
	Set collector_timeout based on the `tick' count returned.
	(profile_waiter): Use MAX_PC_SAMPLES.  Set nsamples before RPC.
	Use collector_timeout in __mach_msg call.

	* gmon/Makefile (noprof): New variable containing mcount.
	Append profil unless it is in $(unix-syscalls).
	(mcount.po): Use $(noprof) for list of targets in this rule.

	* libc-symbols.h: Define _LIBC before #include <config.h>.

Sun Feb 25 12:29:23 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* config.h.in [_LIBC] (HAVE_STRERROR): Define it.
	Protect 2nd page of #undef's for generator programs with #ifndef _LIBC.

	* time/zic.c, time/zdump.c, time/private.h: Updated from ADO's latest.

Fri Feb  9 12:40:19 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>

 	* libio/cleanup.c (_IO_cleanup_registration_needed)
	[!_G_HAVE_ATEXIT]: Init to NULL.
	* libio/filedoalloc.c (_IO_cleanup_registration_needed): Remove decl.

Thu Feb  8 08:12:50 1996  Brendan Kehoe  <brendan@cygnus.com>

	* libio/filedoalloc.c (_IO_cleanup_registration_needed): Revert
	previous change, since cleanup.c only defines it if _G_HAVE_ATEXIT.

Wed Feb  7 15:10:17 1996  Brendan Kehoe  <brendan@lisa.cygnus.com>

	* libio/filedoalloc.c (_IO_cleanup_registration_needed): Declare as
	extern.

Sat Feb 24 11:34:13 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* sysdeps/i386/memcmp.S: Fix argument %esp offsets.

	* time/sys/time.h (timeradd, timersub): New macros; BSD has these.
1996-02-27 00:55:03 +00:00
Roland McGrath a182affdd9 Wed Feb 21 02:25:07 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* Rules (others): Depend on $(extra-objs), $(install-lib),
	$(install-bin), $(install-sbin), in object directory.

	* Makeconfig (link-libc): Don't pass -rpath option with default
	path, since ld.so should use the same default.
	* Makerules (build-shlib): Likewise.

	* Makerules (make-target-directory): Use mkinstalldirs.

	* sysdeps/mach/i386/sysdep.h: Include unix/i386/sysdep.h to
	redefine ENTRY et al.

	* sysdeps/unix/sysv/linux/i386/sysdep.h (NO_UNDERSCORES, ENTRY):
	Macros removed.  The code in unix/i386/sysdep.h should now suffice.

	* sysdeps/unix/i386/sysdep.h (ALIGNARG): New macro, defns for
	[HAVE_ELF] and not.
	(ENTRY): Use it in .align directive.
	(CALL_MCOUNT): New macro, empty unless [PROF].
	(ENTRY): Do CALL_MCOUNT just after the label.

	* Makeconfig (CPPFLAGS-.po): New variable, use -DPROF so assembly
	code can call mcount.

Tue Feb 20 23:05:16 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* time/private.h, time/zdump.c, time/zic.c: Updated verbatim from ADO;
	translation markings are now integrated in his distribution.

	* stdlib/strtod.c (round_and_return): Add missing (mp_limb) 1 cast.

	* po: New directory where `LANG.po' files for message translations
	will reside.
	* po/SYS_libc.pot: New file, template of message strings as in source.
	* MakeTAGS: New rules to build po/SYS_libc.pot automatically from
	the source using xgettext.
	* Makerules ($(..)po/%.pot): New rule.
	* manual/Makefile (../po/manual.pot): New target, make it empty.

	* sysdeps/unix/bsd/alarm.c: Moved to sysdeps/unix/alarm.c.
	* sysdeps/unix/bsd/nice.c: Moved to sysdeps/unix/nice.c.
	* sysdeps/unix/bsd/stime.c: Moved to sysdeps/unix/stime.c.
	* sysdeps/unix/bsd/time.c: Moved to sysdeps/unix/time.c.
	* sysdeps/unix/bsd/utime.c: Moved to sysdeps/unix/utime.c.
1996-02-22 15:52:20 +00:00
Roland McGrath f2e235b9b8 Mon Feb 19 18:31:59 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* time/zic.c, time/scheck.c, time/private.h, time/tzfile.h:
	Updated from ADO 96d.
1996-02-19 23:34:46 +00:00
Roland McGrath 0ddc0d1604 Sun Feb 18 14:08:04 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* csu/initfini.c (_init): Remove bogus volatile declarations and
	extra variable, take the address of __gmon_start__ only implicitly
	to avoid the test being optimized out.
1996-02-19 23:25:15 +00:00
Roland McGrath bfc04a9ff1 Sun Feb 18 15:08:10 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/posix/utimes.c (__utimes): There are 1000000 usecs in a
	sec.

Sun Feb 18 13:56:00 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* elf/Makefile, time/Makefile: Make `all' the default target.

Mon Feb 19 18:09:04 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* misc/sys/ptrace.h: Moved to ...
	* sysdeps/generic/sys/ptrace.h: ... here.
	* sys/ptrace.h: File removed.

Sun Feb 18 12:13:07 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/Makefile (headers): Add fpu_control.h.

	* sysdeps/unix/sysv/linux/i386/sysdep.S (errno): Put it into .bss
 	so that the symbol alias works.

	* sysdeps/unix/sysv/linux/m68k/fpu_control.h (_FPU_SETCW): Corrected.

	* sysdeps/unix/sysv/linux/resourcebits.h: New file.

	* sysdeps/unix/sysv/linux/sys/ptrace.h: New file.

	* sysdeps/unix/sysv/linux/syscalls.list: Add getegid, geteuid,
	getppid and reboot.

	* sysdeps/unix/sysv/linux/sysconf.c: Special version that does not
	use getdtablesize.

Sat Feb 17 10:30:21 1996  David Mosberger-Tang  <davidm@AZStarNet.com>

	* stdio-common/printf_fp.c, stdlib/strtod.c, sysdeps/ieee754/dbl2mpn.c,
	sysdeps/ieee754/ldbl2mpn.c, sysdeps/ieee754/mpn2dbl.c,
	sysdeps/ieee754/mpn2ldbl.c: Cast left operands of shift instructions
	to `long' where necessary.

Thu Feb 15 20:04:50 1996  Ulrich Drepper  <drepper@gnu.ai.mit.edu>

	* stdlib/fpioconst.h: Introduce new constant _FPIO_CONST_OFFSET.
	* stdio-common/printf_fp.c, stdlib/strtod.c: Use _FPIO_CONST_OFFSET
	to correctly access MPN array depending on architecture.
1996-02-19 23:14:44 +00:00
Roland McGrath be10a86854 *** empty log message ***
Mon Feb 19 15:30:26 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* stdio-common/tstscanf.c (main): Add check for "0" as %d.

	* sysdeps/stub/msync.c: Undo change of Jan 29; just two args.
	Only some systems have three args; let them define their own stub.

	* sysdeps/generic/dl-sysdep.c: Declare _dl_secure.

	* sysdeps/generic/machine-gmon.h: New file.
	* gmon/Makefile (distribute): Add machine-gmon.h.
	* gmon/mcount.c: Undo changes of Feb 13.
	Include "machine-gmon.h".

Sun Feb 18 13:24:06 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* sysdeps/unix/sysv/linux/direct.h: File removed, since it is
	identical to unix/common/direct.h.

	* sysdeps/unix/Makefile [no_deps]: Don't include s-proto.d.

	* sysdeps/unix/sysv/linux/Makefile (sysdep_routines): Don't add ipc.

	* stdio-common/Makefile (tests): Remove scanf6.

	* sysdeps/unix/sysv/linux/Makefile (non-lib.a): Append libieee.a.

	* time/mktime.c (mktime): Move static variable localtime_offset to
	file scope.

	* stdio-common/vfscanf.c: Put '0' in buffer before scanning for %i
	base indicator.

Thu Feb 15 16:56:17 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/m68k/dl-machine.h (elf_machine_load_address): Corrected.
	(ELF_MACHINE_BEFORE_RTLD_RELOC): Define.
	(_dl_runtime_resolve): Save %a1 as well.
	(ELF_MACHINE_RUNTIME_FIXUP_ARGS): Add second dummy arg.
	(elf_machine_relplt): Define.

	* elf/dl-runtime.c: Include possible extra args in declaration of
 	fixup.
1996-02-19 20:54:38 +00:00
Roland McGrath 1cbca0d93c Fri Feb 16 11:01:59 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* time/tzset.c: Limit hours to 23, not 12.  From jaffer.
1996-02-16 16:15:45 +00:00
Roland McGrath 7c97bb094e Fri Feb 16 10:14:05 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* Makeconfig (CFLAGS-.po): Use -pg instead of -p.
1996-02-16 15:14:24 +00:00
Roland McGrath 9b19f55dc8 Thu Feb 15 11:49:45 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/sysv/sysv4/Makefile [$(subdir)-signal]
	(sysdep_routines): Don't add sys-sig.

	* sysdeps/unix/sysv/sysv4/solaris2/syscalls.list: New file.
1996-02-16 14:47:21 +00:00
Roland McGrath 9e3db9cd59 Thu Feb 15 13:57:08 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* mach/Machrules: Use -include for $(*.ir).

	* hurd/hurd/ioctl.h (_HURD_HANDLE_IOCTLS): Mask off type bits in
	request values.
	* sysdeps/mach/hurd/ioctls.h (_IOC_NOTYPE): New macro.
	(_IOT_COUNT2): Field is 3 bits, not 2.
	* sysdeps/mach/hurd/ioctl.c: Ignore handler if it fails with ENOTTY.
	* hurd/hurdioctl.c (_hurd_lookup_ioctl_handler): Mask off type
	bits before looking up handler.
	(fioctl): Use __hurd_dfail.
	(fioctl, fioclex): Use ENOTTY for bogus request instead of EGRATUITOUS.

Wed Feb 14 00:21:17 1996 David Mosberger-Tang  <davidm@azstarnet.com>

	* sysdeps/alpha/memchr.c (memchr): loop searching for matching
	character bailed out one too early; changed constant 6 to
	7 to fix this.
1996-02-16 02:19:52 +00:00
Roland McGrath a1c46301bb * posix/execvp.c: When executing shell on script, first arg is
full file name, not argv[0].

	* mach/Makefile [no_deps]: Inhibit inclusion of mach-syscalls.mk.
	* mach/Machrules [no_deps]: Inhibit interface rules.
1996-02-14 06:39:32 +00:00
Roland McGrath de1b40af73 Wed Feb 14 01:08:58 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* malloc/Makefile (distribute): Removed TODO.

	* sysdeps/unix/sysv/linux/syscalls.list (ipc): Specify msgget in
	caller column.
1996-02-14 06:09:19 +00:00
Miles Bader e335fa388a Updated from ../gpl2lgpl.sed /home/gd/gnu/lib/getopt.c 1996-02-13 18:28:59 +00:00
Roland McGrath c6de696871 (ipc): Specify msgget in caller column. 1996-02-13 16:09:47 +00:00
Roland McGrath ae4c4dae36 * sysdeps/unix/common/syscalls.list: Add sigaction syscall. 1996-02-13 11:53:03 +00:00
Roland McGrath d2c2312316 * elf/dl-runtime.c (fixup) [ELF_MACHINE_RUNTIME_FIXUP_ARGS]: Let
this macro declare extra leading args.

	* Makerules [$(elf)=yes] (ar-symtab-name): Define to empty.
1996-02-13 11:49:42 +00:00
Roland McGrath 13987e686c New file from Schwab
* sysdeps/unix/sysv/linux/m68k/fpu_control.h: New file.
1996-02-13 11:40:36 +00:00
Roland McGrath 46d7de1907 Sat Feb 10 13:09:03 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/m68k/brk.c,
	sysdeps/unix/sysv/linux/m68k/mmap.S,
	sysdeps/unix/sysv/linux/m68k/select.S,
	sysdeps/unix/sysv/linux/m68k/sigcontext.h,
	sysdeps/unix/sysv/linux/m68k/sigreturn.S,
	sysdeps/unix/sysv/linux/m68k/socket.S,
	sysdeps/unix/sysv/linux/m68k/syscall.S,
	sysdeps/unix/sysv/linux/m68k/sysdep.S,
	sysdeps/unix/sysv/linux/m68k/sysdep.h: New files.
	* sysdeps/unix/sysv/linux/m68k/brk.c,
	sysdeps/unix/sysv/linux/m68k/mmap.S,
	sysdeps/unix/sysv/linux/m68k/select.S,
	sysdeps/unix/sysv/linux/m68k/sigcontext.h,
	sysdeps/unix/sysv/linux/m68k/sigreturn.S,
	sysdeps/unix/sysv/linux/m68k/socket.S,
	sysdeps/unix/sysv/linux/m68k/syscall.S,
	sysdeps/unix/sysv/linux/m68k/sysdep.S,
	sysdeps/unix/sysv/linux/m68k/sysdep.h: New files.
1996-02-13 11:38:58 +00:00
Roland McGrath 4eea716e2d i386/gnu/types.h moved to top-level linux dir.
* sysdeps/unix/sysv/linux/gnu/types.h: Moved from linux/i386.
1996-02-13 11:35:47 +00:00
Roland McGrath 2a072de4a1 Tue Feb 13 05:12:02 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/Makefile [$(subdir)=math]
	(sysdep_routines): Append setfpucw.
	(extra-objs): Append ieee-fpucw.o.
	(install-lib): Append libieee.a.
	(libieee.a): New target.
	* sysdeps/unix/sysv/linux/ieee-fpucw.c: New file.
	* sysdeps/unix/sysv/linux/i386/fpu_control.h
	(_FPU_GETCW, _FPU_SETCW): New macros.
	(fpu_control_t): New typedef.
	(__setfpucw): Use fpu_control_t for argument type.
	* sysdeps/unix/sysv/linux/fpu_control.c: Moved from linux/i386.

	* sysdeps/unix/sysv/linux/init-first.c: Moved from linux/i386.
	* sysdeps/unix/sysv/linux/Makefile [$(subdir)=math]
	(sysdep_routines): Append setfpucw.
	(extra-objs): Append ieee-fpucw.o.
	(install-lib): Append libieee.a.
	(libieee.a): New target.
	* sysdeps/unix/sysv/linux/ieee-fpucw.c: New file.
	* sysdeps/unix/sysv/linux/i386/fpu_control.h
	(_FPU_GETCW, _FPU_SETCW): New macros.
	(fpu_control_t): New typedef.
	(__setfpucw): Use fpu_control_t for argument type.
	* sysdeps/unix/sysv/linux/fpu_control.c: Moved from linux/i386.

	* sysdeps/unix/sysv/linux/init-first.c: Moved from linux/i386.
1996-02-13 11:07:05 +00:00
Roland McGrath 363113d02a Tue Feb 13 05:12:02 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/syscalls.list: Add ipc syscall.
	* sysdeps/unix/sysv/linux/i386/syscalls.list: File removed.
Tue Feb 13 05:12:02 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* sysdeps/unix/sysv/linux/syscalls.list: Add ipc syscall.
	* sysdeps/unix/sysv/linux/i386/syscalls.list: File removed.
1996-02-13 10:16:25 +00:00
Roland McGrath 3585d6bf30 Sat Feb 10 13:09:03 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c,
	sysdeps/m68k/isinfl.c, sysdeps/m68k/isnanl.c: New files.
	* sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c,
	sysdeps/m68k/isinfl.c, sysdeps/m68k/isnanl.c: New files.
1996-02-13 09:51:13 +00:00
Roland McGrath 01f3e03bcd Sat Feb 10 13:09:03 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/unix/sysv/linux/sys/mman.h: Define MAP_ANON and
	MAP_FILE if not already defined.

	* elf/elf.h: Add m68k reloc definitions.
	* sysdeps/m68k/dl-machine.h, sysdeps/m68k/elf/start.S: New files.
Sat Feb 10 13:09:03 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/sys/mman.h: Define MAP_ANON and
	MAP_FILE if not already defined.

	* elf/elf.h: Add m68k reloc definitions.
	* sysdeps/m68k/dl-machine.h, sysdeps/m68k/elf/start.S: New files.
1996-02-13 09:26:53 +00:00
Roland McGrath 38334018ff Tue Feb 13 00:12:12 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/i386/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE,
	elf_machine_relplt): New macros.
	* elf/dl-runtime.c: New file.
	* sysdeps/i386/dl-runtime.c, sysdeps/stub/dl-runtime.c: Files removed.
	* sysdeps/i386/dl-machine.h (ELF_MACHINE_RUNTIME_TRAMPOLINE,
	elf_machine_relplt): New macros.
	* elf/dl-runtime.c: New file.
	* sysdeps/i386/dl-runtime.c, sysdeps/stub/dl-runtime.c: Files removed.
1996-02-13 07:05:16 +00:00
Roland McGrath dbdb6189d5 Tue Feb 13 00:12:12 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* gmon/Makefile (headers): Remove machine-gmon.h.
	* sysdeps/stub/machine-gmon.h, sysdeps/i386/machine-gmon.h: Removed.
	* gmon/mcount.c [! NO_UNDERSCORES] (_mcount): Specify "mcount" as
	the asm name.
	(_mcount): Define normally, taking no args.
	Use __builtin_return_address to fetch PC values of caller and caller's
	caller.
Tue Feb 13 00:12:12 1996  Roland McGrath  <roland@charlie-brown.gnu.ai.mit.edu>

	* gmon/Makefile (headers): Remove machine-gmon.h.
	* sysdeps/stub/machine-gmon.h, sysdeps/i386/machine-gmon.h: Removed.
	* gmon/mcount.c [! NO_UNDERSCORES] (_mcount): Specify "mcount" as
	the asm name.
	(_mcount): Define normally, taking no args.
	Use __builtin_return_address to fetch PC values of caller and caller's
	caller.

	* Makerules: Rewrote rules to update libc archives of all flavors.
	Define separate specific rules for each flavor using o-iterator.

	* sysdeps/unix/Makefile: Include s-proto.d only ifdef subdir.

Sat Feb 10 11:35:16 1996 Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makerules (ar-symtab-name): New macro.  Replace all occurences
	of __.SYMDEF by $(ar-symtab-name).
	* sysdeps/unix/sysv/Makefile (ar-symtab-name): Define as empty.

	* Makefile (configure, %/configure): Depend on aclocal.m4.
	* Make-dist (configure, %/configure): Likewise.

	* sysdeps/unix/Makefile: Include s-proto.d for its deps.

	* gmon/sys/gmon.h: Don't include machine-gmon.h; those defns are
	only needed in the implementation, not for any users.

	* time/northamerica: Updated from ADO 96c, new rules for Mexico in
	1996.
1996-02-13 05:46:59 +00:00
Roland McGrath afced61c8f Updated from ADO 96c, new rules for Mexico in 1996. 1996-02-13 03:56:17 +00:00
Doug Evans d592cd699d Recognize sparclet cpu. 1996-02-12 23:15:30 +00:00
Per Bothner a7cb7644cf * config.guess (UNAME_VERSION): Recognize X4.x as an OSF version. * config.guess (*:CYGWIN*): New 1996-02-12 20:55:56 +00:00
Per Bothner 889a9677fd * config.guess: Support m68k-cbm-sysv4. * config.guess (*:Linux:*:*): Guess m68k-unknown-linux 1996-02-12 20:44:56 +00:00
Roland McGrath 25f9784eb8 * sunrpc/pm_getport.c: #if 0 out gratuitous inclusion of <net/if.h>.
* sunrpc/pm_getmaps.c: Likewise.
1996-02-12 10:36:01 +00:00
Roland McGrath 1fe58993bc * sysdeps/unix/sysv/syscalls.list: Add setrlimit and settimeofday,
so real syscalls override unix/sysv/*.c on sysv-derived systems
 	that have them.
	* sysdeps/unix/common/syscalls.list: Add settimeofday here, to
	override unix/sysv/settimeofday.c since that overrides
	unix/syscalls.list.

	* Makeconfig (+link): Put $(link-libc) after deps from $^,
	regardless of where libc.a appears in the deps.
1996-02-12 10:23:47 +00:00
Roland McGrath 63f8940402 * hurd/hurdfault.c (_hurdsig_fault_init): Set qlimit on
FORWARD_SIGEXC to one.  Uncomment setting of thread exc port, and
 	move it to last thing.
1996-02-12 10:00:30 +00:00
Roland McGrath 808c413c90 Mon Feb 12 03:10:41 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/unix/sysv/sysv4/syscalls.list: Remove redundancies.
	Add __waitid.
	* sysdeps/unix/sysv/linux/syscalls.list: Remove redundancies.
	Define __ name for sigprocmask.
	* sysdeps/unix/bsd/ultrix4/syscalls.list: Remove redundancies.
	Add getsysinfo.
	* sysdeps/unix/bsd/sun/sunos4/syscalls.list: Remove redundancies.
	* sysdeps/unix/bsd/sun/syscalls.list: Remove redundancies.
	* sysdeps/unix/bsd/bsd4.4/syscalls.list: Remove redundancies.
	* sysdeps/unix/bsd/syscalls.list: Remove settimeofday, utimes.
	Add getdents, wait3, waitpid.
	* sysdeps/unix/syscalls.list: Add seteuid, setegid, setsid,
	settimeofday, sigsuspend, sstk, utimes.
	* sysdeps/unix/bsd/ultrix4/mips/sigvec.S: File removed.
	* sysdeps/unix/bsd/ultrix4/mips/syscalls.list: New file.
	* sysdeps/unix/bsd/ultrix4/mips/Makefile (sysdep_routines):
	Removed sigtramp.
	* sysdeps/unix/bsd/ultrix4/mips/sigvec.c: Renamed from sigtramp.c.
	* sysdeps/unix/bsd/bsd4.4/sstk.S: File removed.
	* sysdeps/unix/bsd/hp/m68k/syscalls.list: File removed.
	* sysdeps/unix/bsd/osf/alpha/getdents.S: File removed.
	* sysdeps/unix/bsd/ultrix4/getsysinfo.S: File removed.
	* sysdeps/unix/bsd/ultrix4/waitpid.S: File removed.
	* sysdeps/unix/bsd/ultrix4/mips/sigtramp.c: File removed.
	* sysdeps/unix/bsd/ultrix4/mips/sigvec.S: File removed.
	* sysdeps/unix/bsd/ultrix4/mips/sigvec.c: New file.
	* sysdeps/unix/bsd/ultrix4/mips/syscalls.list: New file.
	* sysdeps/unix/sysv/irix4/wait3.S: File removed.
	* sysdeps/unix/sysv/sysv4/__waitid.S: File removed.
	* sysdeps/unix/sysv/sysv4/fchdir.S: File removed.
	* sysdeps/unix/sysv/sysv4/setegid.S: File removed.
	* sysdeps/unix/sysv/sysv4/seteuid.S: File removed.
	* sysdeps/unix/sysv/sysv4/sigaltstack.S: File removed.
	* sysdeps/unix/sysv/sysv4/solaris2/utimes.S: File removed.
1996-02-12 08:37:31 +00:00
Roland McGrath 47665862cd (sysdep_routines): Removed sigtramp. 1996-02-12 08:11:19 +00:00
Richard M. Stallman bdf2af37da Fix typo in previous change. 1996-02-11 23:40:37 +00:00
Roland McGrath 186588d6bf Sat Feb 10 05:57:08 1996 Roland McGrath <roland@charlie-brown.gnu.ai.mit.edu>
* sysdeps/generic/make_siglist.c: #undef _SIGNAL_H before defining it.

	* sysdeps/unix/sysv/linux/syscalls.list: Add sigprocmask, sigsuspend.
1996-02-11 10:00:24 +00:00
Richard Kenner 3038e60115 (-psos*): New case. 1996-02-10 13:26:26 +00:00
Roland McGrath 932be5efa3 #undef _SIGNAL_H before defining it. 1996-02-10 11:19:12 +00:00
Roland McGrath 6a032d8158 Sat Feb 10 04:18:48 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* posix/execvp.c: If execv fails with ENOEXEC, run the shell on
	the file.

Fri Feb  9 11:46:45 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* time/Makefile (CFLAGS-zdump.c, CFLAGS-zic.c, CFLAGS-ialloc.c,
	CFLAGS-scheck.c): Use -DNOID instead of -Wno-unused.

	* hurd/Makefile (user-interfaces): Added hurd/tioctl.
1996-02-10 10:00:27 +00:00
Roland McGrath 56f778c958 Thu Feb 8 18:55:27 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* hurd/hurdioctl.c (tiocsctty): Set the terminal's pgrp to our own.
1996-02-09 10:00:23 +00:00
Roland McGrath a482b5a595 * Makefile (subdirs): Added wcsmbs.
* wcsmbs: New directory of wide char/multibyte char functions from
	drepper.
1996-02-08 10:00:34 +00:00
Roland McGrath 4ca84cff3b Wed Feb 7 18:48:30 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* hurd/hurdmsg.c (_S_msg_report_wait): Function removed.
	* hurd/report-wait.c: New file.
	* hurd/Makefile (routines): Added report-wait.

	* sysdeps/mach/hurd/Makefile (inhibit-unix-syscalls): New variable.

	* sysdeps/mach/hurd/i386/intr-msg.h (struct mach_msg_trap_args):
	New type.
	(SYSCALL_EXAMINE, MSG_EXAMINE): New inline functions.
	* sysdeps/mach/hurd/i386/trampoline.c (struct mach_msg_trap_args):
	Structure moved to intr-msg.h; include that.

	* time/Makefile (CFLAGS-ialloc.c): Add -Wno-unused.
	(CFLAGS-scheck.c): New variable.

	* sysdeps/mach/hurd/dl-sysdep.c (__hurd_sigthread_stack_base,
	__hurd_sigthread_stack_end, __hurd_sigthread_variables,
	__hurd_threadvar_stack_mask): New variables.

	* sysdeps/mach/hurd/fork.c: Set the new task's exception port to
	its new message port.

	* misc/init-misc.c: Put __init_misc in the __libc_subinit set.

	* configure.in (uname): Add quoting.

	* sysdeps/mach/hurd/fchdir.c: Don't consult errno unless lookup fails.
	* hurd/fchroot.c: Likewise.

	* posix/sys/types.h [GCC >= 2.7]: Define intN_t/u_intN_t using
	__attribute__ ((__mode__ (__XX__))).

Wed Feb 7 03:24:05 1996 Torbjorn Granlund  <tege@tmg.se>

	* sysdeps/i386/i586/memcopy.h (WORD_COPY_FWD): Manually allocate
	destination cache lines.
	(WORD_COPY_BWD): Likewise.

Wed Feb  7 14:16:36 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* sysdeps/generic/Makefile (make_siglist): Get signum.h absolute
	file name first thing, before $(native-compile) changes directories.

	From Gord Matzigkeit <gord@enci.ucalgary.ca>:
	* sysdeps/unix/make_errlist.c: Use strerror if available.
	* sysdeps/unix/configure.in: New file

	* sysdeps/unix/bsd/sun/syscalls.list: Added sigvec.
	* sysdeps/unix/bsd/sun/sigvec.S: File removed.

	* sysdeps/stub/sendto.c: Make sockaddr arg pointer to const.
	* sysdeps/stub/connect.c: Likewise.
	* sysdeps/stub/bind.c: Likewise.

	* hurd/hurdlookup.c (__hurd_file_name_lookup_retry): RETRYNAME of
	"" is only special for FS_RETRY_NORMAL; for FS_RETRY_REAUTH, do
	another dir_lookup of "".
1996-02-08 02:10:15 +00:00
Roland McGrath 1ac3b08e93 Fri Feb 2 13:09:18 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/fork.c: Clear trace flag in child.
1996-02-03 10:00:25 +00:00
Michael Meissner c09ebb85ba Add cygwin32; Put eabi .sdata2/.sbss2 into read-only memory 1996-02-03 01:03:27 +00:00
Roland McGrath b07c5668f6 Updated from ../gpl2lgpl.sed /home/gd/gnu/lib/getopt.c 1996-02-02 18:41:42 +00:00
Roland McGrath 5413944738 Wed Jan 31 20:08:26 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* hurd/intr-msg.c (_hurd_intr_rpc_mach_msg): Clear SS->intr_port
	when cancelled before RPC.
1996-02-01 10:00:23 +00:00
Roland McGrath b18c76e9f5 (_hurd_intr_rpc_mach_msg): Clear SS->intr_port when cancelled before RPC. 1996-02-01 01:08:12 +00:00
Ian 635a540581 Add support for A/UX 1996-01-31 19:14:05 +00:00
Ian 4505e8c1ed Recognize A/UX 1996-01-31 19:10:52 +00:00
Roland McGrath 01cdeca0c9 Tue Jan 30 13:32:05 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* dirent/scandir.c: Allocate dirents with correct size for name, and
	copy with correct size.

	* hurd/hurdinit.c [! PIC] (map0): New function, on _hurd_preinit_hook.

	* stdio-common/vfscanf.c (TYPEMOD): New macro of all type modifier
	flag bits.
	(__vfscanf): Fix checking of extra type modifiers.

	* time/asia, time/australasia, time/backward: Updated from ADO 96b.

Tue Jan 30 12:17:26 1996  Ulrich Drepper  <drepper@ipd.info.uni-karlsruhe.de>

	* stdlib/strtod.c: Only negate exponent when there really is one.

	* stdio-common/vfscanf.c: Accept type modifiers on %n.
	Fix FP number parsing.
1996-01-31 10:00:24 +00:00
Roland McGrath f0b1101835 Mon Jan 29 21:53:40 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/stub/msync.c (msync): Declare third arg FLAGS.

	* resolv/Makefile (+cflags): Append to this instead of CFLAGS.

Mon Jan 29 16:29:16 1996  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/select.c (__select): Recalculate GOT to
 	include an increment for each operation allowed on each fd.

Mon Jan 29 11:44:38 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* sysdeps/unix/sysv/linux/configure: Set $inhibit_glue.

	* Makefile: Use -include for sysd-dirs.

	* configure.in (uname): Check for uname in syscalls.list files.
	* sysdeps/unix/sysv/syscalls.list: Remove uname.
	* sysdeps/unix/syscalls.list: Add uname.

	* stdlib/strtol.c (weak1): New macro, to get the right name declared
	weak.

	* sysdeps/posix/getcwd.c (size_t): Don't define #ifdef __GNU_LIBRARY__.

	* db/hash/ndbm.c: Change all uses of `errno' struct member to `errnum'.
	(dbm_open): Use dynamic allocation for file name buffer, instead of
	limitting its size to MAXPATHLEN.

	* db/btree/bt_open.c (tmp): Use dynamic allocation for file name
	buffer, instead of limitting its size to MAXPATHLEN.

	* db/hash/hash.h (HTAB): Rename member `errno' to `errnum'.
	* db/hash/hash.c: Change all uses of `errno' struct member to `errnum'.
1996-01-30 10:00:24 +00:00
Roland McGrath f3fc970dae (+cflags): Append to this instead of CFLAGS. 1996-01-30 02:53:27 +00:00
Miles Bader 924940c120 (__select): Recalculate GOT to include an increment for each operation allowed on each fd. 1996-01-29 21:45:43 +00:00
Roland McGrath b86199fb60 Set $inhibit_glue. 1996-01-29 19:30:15 +00:00
Roland McGrath 429ed67ba1 Sun Jan 28 19:42:04 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* time/Makefile: Fix check for cross compiling.
Sun Jan 28 19:42:04 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* time/Makefile: Fix check for cross compiling.
1996-01-29 16:11:27 +00:00
Roland McGrath 19c3f20809 Thu Jan 25 21:10:39 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* db/Makefile (subdir-dirs): Renamed from dbdirs.

	* Makerules (distinfo-vars): Add subdir-dirs.

	* MakeTAGS: Remove vpath directives.
	(all-dirs): Prepend $(subdir-dirs).
	(all-sources, all-headers): Use wildcard to find sources.
Thu Jan 25 21:10:39 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* db/Makefile (subdir-dirs): Renamed from dbdirs.

	* Makerules (distinfo-vars): Add subdir-dirs.

	* MakeTAGS: Remove vpath directives.
	(all-dirs): Prepend $(subdir-dirs).
	(all-sources, all-headers): Use wildcard to find sources.

Mon Jan 29 10:44:38 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* malloc/Makefile (CFLAGS-vm-limit.c, CFLAGS-ralloc.c): New
	variables.

	* mach/msgserver.c: Declare DEMUX arg with prototype.
1996-01-29 16:05:21 +00:00
Roland McGrath dc825f85f4 Sun Jan 28 17:25:38 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* setjmp/setjmp.h (jmp_buf): Give a tag in the struct defn, to
	make C++ happy.
	* alpha/jmp_buf.h: Likewise.
	* m68k/jmp_buf.h: Likewise.
	* mips/jmp_buf.h: Likewise.
	* sparc/jmp_buf.h: Likewise.
	* vax/jmp_buf.h: Likewise.
Sun Jan 28 17:25:38 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* setjmp/setjmp.h (jmp_buf): Give a tag in the struct defn, to
	make C++ happy.
	* alpha/jmp_buf.h: Likewise.
	* m68k/jmp_buf.h: Likewise.
	* mips/jmp_buf.h: Likewise.
	* sparc/jmp_buf.h: Likewise.
	* vax/jmp_buf.h: Likewise.

	* sysdeps/generic/memmem.c: Fix return value in case where
	NEEDLE_LEN==0.

	* hurd/hurdlookup.c (__file_name_lookup_under,
	__file_name_lookup): Restrict mode with umask.
	* sysdeps/mach/hurd/xmknod.c: Restrict mode with umask.
	* sysdeps/mach/hurd/mkdir.c: Restrict mode with umask.
1996-01-28 22:47:31 +00:00
Roland McGrath eb8c0f2de5 Fri Jan 26 12:20:45 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* stdlib/strtol.c: Undo last change.  ANSI C changed since the
	draft I checked yesterday.  Sigh.
1996-01-27 10:00:24 +00:00
Roland McGrath 8dad333dce Thu Jan 25 18:58:25 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* stdlib/strtol.c [UNSIGNED]: Don't recognize + or - as sign.
1996-01-26 10:00:23 +00:00
Roland McGrath ebc53fbed0 * malloc/mcheck.c (mabort): Declare prototype. 1996-01-25 10:00:24 +00:00
Roland McGrath 555f3a396a * sysdeps/unix/sysv/linux/fcntlbits.h: Moved from linux/i386.
* Makerules: Use -include for generated makefiles.

	* errno.h: Don't declare errno if it's defined as a macro.
1996-01-24 20:36:21 +00:00
Roland McGrath 914d9d7bdf * stdio-common/vfscanf.c: Disallow l flag after ll or L. 1996-01-24 08:25:13 +00:00
Roland McGrath a66067befe * stdio-common/Makefile (tests): Add scanf[1-9].
* stdio-common/scanf[1-9].c: New files.  Bug tests from hjl.
Wed Jan 24 03:22:07 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* stdio-common/Makefile (tests): Add scanf[1-9].
	* stdio-common/scanf[1-9].c: New files.  Bug tests from hjl.
1996-01-24 08:23:33 +00:00
Roland McGrath 0793d3483a Wed Jan 24 04:18:36 1996 Paul Eggert <eggert@twinsun.com>
* strftime.c (strftime):
	When invoking self, check whether the subsidiary invocation failed.
	Use "???" (not "") to denote unknown time zone information.

	Make this source file portable to standalone contexts (e.g. GNU Emacs).
	<config.h>: Include if HAVE_CONFIG_H is defined.
	(HAVE_LIMITS_H, HAVE_MBLEN, HAVE_TM_ZONE, STDC_HEADERS): New symbols,
	defined if _LIBC or if <config.h> defines them.
	<ansidecl.h>, "../locale/localeinfo.h": Include only if _LIBC.
	<sys/types.h>: New include; some hosts require it for `time_t'.
	<ctype.h>: Include only if HAVE_MBLEN (since it's only needed then).
	<limits.h>: Include only if HAVE_LIMITS_H.
	<stddef.h, stdlib.h, string.h>: Include only if STDC_HEADERS.
	(memcpy): Define in terms of bcopy if !STDC_HEADERS.
	(__P, PTR): Define if not already defined.
	(__tzname, __daylight, __timezone): Remove macros; no longer needed.
	(add, strftime): Don't use NULL, for portability to some weird hosts.
	(fmt): If !_LIBC, don't assume sprintf returns a count.
	(week, strftime): Use old-style function declarations.
	(weekday_name, month_name): New constants.
	(strftime): Use traditional C values if locale support isn't available.
	Use `const' instead of CONST.  For time zones, use tm_zone if
	possible, then fall back on tzname.  Don't check for multibyte
	characters unless mblen is supported.  Use formats like %02d instead
	of %.2d, for portability to older hosts.
Wed Jan 24 04:18:36 1996  Paul Eggert  <eggert@twinsun.com>

	* strftime.c (strftime):
	When invoking self, check whether the subsidiary invocation failed.
	Use "???" (not "") to denote unknown time zone information.

	Make this source file portable to standalone contexts (e.g. GNU Emacs).
	<config.h>: Include if HAVE_CONFIG_H is defined.
	(HAVE_LIMITS_H, HAVE_MBLEN, HAVE_TM_ZONE, STDC_HEADERS): New symbols,
	defined if _LIBC or if <config.h> defines them.
	<ansidecl.h>, "../locale/localeinfo.h": Include only if _LIBC.
	<sys/types.h>: New include; some hosts require it for `time_t'.
	<ctype.h>: Include only if HAVE_MBLEN (since it's only needed then).
	<limits.h>: Include only if HAVE_LIMITS_H.
	<stddef.h, stdlib.h, string.h>: Include only if STDC_HEADERS.
	(memcpy): Define in terms of bcopy if !STDC_HEADERS.
	(__P, PTR): Define if not already defined.
	(__tzname, __daylight, __timezone): Remove macros; no longer needed.
	(add, strftime): Don't use NULL, for portability to some weird hosts.
	(fmt): If !_LIBC, don't assume sprintf returns a count.
	(week, strftime): Use old-style function declarations.
	(weekday_name, month_name): New constants.
	(strftime): Use traditional C values if locale support isn't available.
	Use `const' instead of CONST.  For time zones, use tm_zone if
	possible, then fall back on tzname.  Don't check for multibyte
	characters unless mblen is supported.  Use formats like %02d instead
	of %.2d, for portability to older hosts.

Wed Jan 24 00:07:52 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* stdio-common/vfscanf.c (GROUP, MALLOC): New flag macros.
	(__vfscanf): Eliminate flag vars that were redundant with FLAGS bits.
	Fix bug in recognition of %ll flag for long long.
	Fix overeager checks for conflicting type modifiers.
	With ' flag, match thousands separators for decimal numbers.

Tue Jan 23 22:02:40 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* locale/Makefile (CFLAGS-locfile-lex.c): New variable.

	* resolv/Makefile (CFLAGS): Disable some warnings.

	* sysdeps/generic/Makefile (elided-routines): Removed hypot.
	(+gccwarn): Set with override.

	* stdio-common/Makefile (CFLAGS-tst-printf.c): New variable.

	* posix/Makefile (CFLAGS-regex.c): New variable.

	* malloc/Makefile (CFLAGS-obstack.c): New variable.

	* io/Makefile (CFLAGS-fts.c): New variable.
	* io/fts.c (fts_open): Use prototypes for COMPAR decl.

Tue Jan 23 21:35:32 1996  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/bind.c (bind): Ensure NAME for the AF_LOCAL
	case is '\0'-terminated.

Tue Jan 23 19:49:54 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* elf/rtld.c (dl_main): Support additional args in --list mode for
	debugging: look them up as symbol names and print values.

	* misc/getttyent.c (skip, value): Declare with prototypes in file
	scope.

	* csu/initfini.c (_init): Explicitly set a variable that is
 	pointer to volatile with the address of __gmon_start__, to avoid
 	the test being optimized out.
1996-01-24 06:03:37 +00:00
Roland McGrath 8ebd0a71be (fts_open): Use prototypes for COMPAR decl. 1996-01-24 03:02:14 +00:00
Miles Bader 6d5cbf7b35 (bind): Ensure NAME for the AF_LOCAL case is '\0'-terminated. 1996-01-24 02:39:26 +00:00
Roland McGrath fd86137937 (dl_main): Support additional args in --list mode for debugging: look them up as symbol names and print values. 1996-01-24 01:34:10 +00:00
Roland McGrath 1d8dc4293f Mon Jan 22 10:40:40 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/posix/getcwd.c [__GNU_LIBRARY__]: Include unistd.h.

	* io/fts.h (FTSENT): Define fts_compar member with prototype.

	* hurd/hurd.h: Use prototype in getcttyid decl.

	* stdlib/l64a.c: Fix typo in last change.

	* stdlib/drand48-iter.c: Test limits.h macros instead of sizeof
	for determining size of types.
	* stdlib/srand48_r.c: Likewise.

	* misc/utmp.h: Declare login, logout, logwtmp.
	* misc/logout.c: Declare argument as pointer to const.
	* misc/login.c: Likewise.
	* misc/logwtmp.c: Likewise.
	Include time.h, string.h.

	* misc/efgcvt_r.c: Include stdlib.h.

	* io/mknod.c: Include sys/types.h.

	* gmon/sys/gmon.h: Declare monstartup, _mcleanup.

	* csu/gmon-start.c (_start, etext): Declare with prototypes.

	* stdio-common/vfscanf.c (%[): Fix range handling.
1996-01-23 10:00:23 +00:00
Roland McGrath f2f7f9e665 * misc/Makefile (headers): Rename queue.h to sys/queue.h.
* misc/queue.h: Moved to misc/sys/queue.h.
1996-01-22 10:00:24 +00:00
Roland McGrath bbed653cda Sun Jan 21 00:55:25 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/shmat.c: Include sys/shm.h instead of
	sys/sem.h.

	* stdlib/stdlib.h [__USE_SVID]: Declare a64l, l64a.

	* stdlib/l64a.c: Use 6-bit numbers as indices in CONV_TABLE, not
	literal byte values.

	* misc/bsd-compat.c (getpgrp): Define with prototype.

	* misc/init-misc.c (__progname_full): New variable.
	(program_invocation_name, program_invocation_short_name): New aliases.
	(__init_misc): Define with prototype.  Set __progname_full.
	* misc/progname.c: File removed.
	* misc/Makefile (aux): Remove progname.

	* misc/hsearch_r.c (isprime): Define with prototype.

	* sysdeps/unix/sysv/linux/seteuid.c: Just include unix/bsd version.
	* sysdeps/unix/bsd/seteuid.c: Disallow arg of -1.
	* sysdeps/unix/bsd/setegid.c: Likewise.
1996-01-21 10:01:05 +00:00
Roland McGrath eb63bdd072 * sysdeps/unix/sysv/linux/tcdrain.c: Define tcdrain, not
__tcdrain.

	* posix/glob.c (glob): Use prototype in getlogin decl.

	* db/ndbm.h: Declare dbm_error, dbm_clearerr.
	* db/db/db.c (__dberr): Define with prototype.
	(__dbpanic): Use prototypes in casts.
	* db/hash/hash_log2.c: Add prototype decl.

	* sysdeps/generic/_strerror.c (_strerror_internal): Define with
	prototype.
1996-01-20 10:00:23 +00:00
Roland McGrath 522548fb47 Fri Jan 19 13:28:59 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/mkdir.c, syspdep/unix/rmdir.c: Moved from unix/sysv.
	They will be overridden with syscalls if extant by unix/syscalls.list.
Fri Jan 19 13:28:59 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* sysdeps/unix/mkdir.c, syspdep/unix/rmdir.c: Moved from unix/sysv.
	They will be overridden with syscalls if extant by unix/syscalls.list.

	* Makeconfig (+gccwarn): Add -Wstrict-prototypes.

	* stdio-common/printf_fp.c (__printf_fp): Define with prototype.
	* stdio-common/vfprintf.c (_IO_helper_overflow): Likewise.
1996-01-19 18:43:03 +00:00
Roland McGrath 97aa195cf7 * io/Makefile (routines): Add mknod, xstat fxstat lxstat xmknod.
* sysdeps/unix/sysv/linux/ptrace.c: Use ... decl, and stdarg.h to
	get args.

	* posix/glob.c (_GNU_SOURCE): Define if undefined, so glob.h
	defines GNU extensions.
	* posix/fnmatch.c: Likewise.
1996-01-19 10:00:23 +00:00
Roland McGrath 9b29e6f7a3 Thu Jan 18 00:32:43 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
Replaced all simple system call files *.S throughout sysdeps/unix
	with syscalls.list files to be processed by make-syscalls.sh.
	* sysdeps/unix/s-proto.S: New file.
	* sysdeps/unix/syscalls.list: New file.
	* sysdeps/unix/bsd/syscalls.list: New file.
	* sysdeps/unix/bsd/bsd4.4/syscalls.list: New file.
	* sysdeps/unix/bsd/hp/m68k/syscalls.list: New file.
	* sysdeps/unix/bsd/osf/syscalls.list: New file.
	* sysdeps/unix/bsd/osf/alpha/syscalls.list: New file.
	* sysdeps/unix/bsd/sony/newsos4/syscalls.list: New file.
	* sysdeps/unix/bsd/sun/syscalls.list: New file.
	* sysdeps/unix/bsd/sun/sunos4/syscalls.list: New file.
	* sysdeps/unix/bsd/ultrix4/syscalls.list: New file.
	* sysdeps/unix/common/syscalls.list: New file.
	* sysdeps/unix/inet/syscalls.list: New file.
	* sysdeps/unix/mman/syscalls.list: New file.
	* sysdeps/unix/sysv/syscalls.list: New file.
	* sysdeps/unix/sysv/irix4/syscalls.list: New file.
	* sysdeps/unix/sysv/isc2.2/syscalls.list: New file.
	* sysdeps/unix/sysv/linux/syscalls.list: New file.
	* sysdeps/unix/sysv/linux/i386/syscalls.list: New file.
	* sysdeps/unix/sysv/sco3.2.4/syscalls.list: New file.
	* sysdeps/unix/sysv/sysv4/syscalls.list: New file.
	* sysdeps/unix/sysv/sysv4/i386/syscalls.list: New file.
	* sysdeps/unix/sysv/sysv4/solaris2/sparc/syscalls.list: New file.
	* sysdeps/unix/acct.S: File removed.
	* sysdeps/unix/chdir.S: File removed.
	* sysdeps/unix/chmod.S: File removed.
	* sysdeps/unix/chown.S: File removed.
	* sysdeps/unix/chroot.S: File removed.
	* sysdeps/unix/close.S: File removed.
	* sysdeps/unix/configure: File removed.
	* sysdeps/unix/configure.in: File removed.
	* sysdeps/unix/dup.S: File removed.
	* sysdeps/unix/fcntl.S: File removed.
	* sysdeps/unix/fsync.S: File removed.
	* sysdeps/unix/getgid.S: File removed.
	* sysdeps/unix/getpid.S: File removed.
	* sysdeps/unix/getuid.S: File removed.
	* sysdeps/unix/ioctl.S: File removed.
	* sysdeps/unix/kill.S: File removed.
	* sysdeps/unix/link.S: File removed.
	* sysdeps/unix/lseek.S: File removed.
	* sysdeps/unix/open.S: File removed.
	* sysdeps/unix/ptrace.S: File removed.
	* sysdeps/unix/read.S: File removed.
	* sysdeps/unix/reboot.S: File removed.
	* sysdeps/unix/setgid.S: File removed.
	* sysdeps/unix/setuid.S: File removed.
	* sysdeps/unix/sync.S: File removed.
	* sysdeps/unix/umask.S: File removed.
	* sysdeps/unix/unlink.S: File removed.
	* sysdeps/unix/write.S: File removed.
	* sysdeps/unix/bsd/flock.S: File removed.
	* sysdeps/unix/bsd/getdtsz.S: File removed.
	* sysdeps/unix/bsd/getpagesize.S: File removed.
	* sysdeps/unix/bsd/killpg.S: File removed.
	* sysdeps/unix/bsd/profil.S: File removed.
	* sysdeps/unix/bsd/readv.S: File removed.
	* sysdeps/unix/bsd/settimeofday.S: File removed.
	* sysdeps/unix/bsd/sigblock.S: File removed.
	* sysdeps/unix/bsd/sigpause.S: File removed.
	* sysdeps/unix/bsd/sigsetmask.S: File removed.
	* sysdeps/unix/bsd/sigstack.S: File removed.
	* sysdeps/unix/bsd/sigvec.S: File removed.
	* sysdeps/unix/bsd/utimes.S: File removed.
	* sysdeps/unix/bsd/writev.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/chflags.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/fchdir.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/fchflags.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/getdents.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/getdomain.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/revoke.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setdomain.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setegid.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/seteuid.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setlogin.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setsid.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/sigaltstack.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/wait4.S: File removed.
	* sysdeps/unix/bsd/hp/m68k/getdents.S: File removed.
	* sysdeps/unix/bsd/osf/msync.S: File removed.
	* sysdeps/unix/bsd/osf/alpha/wait4.S: File removed.
	* sysdeps/unix/bsd/sony/newsos4/fchdir.S: File removed.
	* sysdeps/unix/bsd/sony/newsos4/sys_wait4.S: File removed.
	* sysdeps/unix/bsd/sun/getdents.S: File removed.
	* sysdeps/unix/bsd/sun/sunos3/m68k/wait.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/msync.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/poll.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/setsid.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/sys_mmap.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/sys_wait4.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/uname.S: File removed.
	* sysdeps/unix/bsd/ultrix4/getdents.S: File removed.
	* sysdeps/unix/bsd/ultrix4/setsid.S: File removed.
	* sysdeps/unix/bsd/ultrix4/uname.S: File removed.
	* sysdeps/unix/common/access.S: File removed.
	* sysdeps/unix/common/adjtime.S: File removed.
	* sysdeps/unix/common/dup2.S: File removed.
	* sysdeps/unix/common/fchmod.S: File removed.
	* sysdeps/unix/common/fchown.S: File removed.
	* sysdeps/unix/common/ftruncate.S: File removed.
	* sysdeps/unix/common/getgroups.S: File removed.
	* sysdeps/unix/common/getitimer.S: File removed.
	* sysdeps/unix/common/getpgid.S: File removed.
	* sysdeps/unix/common/getpriority.S: File removed.
	* sysdeps/unix/common/getrlimit.S: File removed.
	* sysdeps/unix/common/getrusage.S: File removed.
	* sysdeps/unix/common/gettimeofday.S: File removed.
	* sysdeps/unix/common/mkdir.S: File removed.
	* sysdeps/unix/common/readlink.S: File removed.
	* sysdeps/unix/common/rename.S: File removed.
	* sysdeps/unix/common/rmdir.S: File removed.
	* sysdeps/unix/common/select.S: File removed.
	* sysdeps/unix/common/setgroups.S: File removed.
	* sysdeps/unix/common/setitimer.S: File removed.
	* sysdeps/unix/common/setpgid.S: File removed.
	* sysdeps/unix/common/setpriority.S: File removed.
	* sysdeps/unix/common/setregid.S: File removed.
	* sysdeps/unix/common/setreuid.S: File removed.
	* sysdeps/unix/common/setrlimit.S: File removed.
	* sysdeps/unix/common/swapon.S: File removed.
	* sysdeps/unix/common/symlink.S: File removed.
	* sysdeps/unix/common/truncate.S: File removed.
	* sysdeps/unix/common/vhangup.S: File removed.
	* sysdeps/unix/inet/accept.S: File removed.
	* sysdeps/unix/inet/bind.S: File removed.
	* sysdeps/unix/inet/connect.S: File removed.
	* sysdeps/unix/inet/gethostid.S: File removed.
	* sysdeps/unix/inet/gethostname.S: File removed.
	* sysdeps/unix/inet/getpeername.S: File removed.
	* sysdeps/unix/inet/getsockname.S: File removed.
	* sysdeps/unix/inet/getsockopt.S: File removed.
	* sysdeps/unix/inet/listen.S: File removed.
	* sysdeps/unix/inet/recv.S: File removed.
	* sysdeps/unix/inet/recvfrom.S: File removed.
	* sysdeps/unix/inet/recvmsg.S: File removed.
	* sysdeps/unix/inet/send.S: File removed.
	* sysdeps/unix/inet/sendmsg.S: File removed.
	* sysdeps/unix/inet/sendto.S: File removed.
	* sysdeps/unix/inet/sethostid.S: File removed.
	* sysdeps/unix/inet/sethostname.S: File removed.
	* sysdeps/unix/inet/setsockopt.S: File removed.
	* sysdeps/unix/inet/shutdown.S: File removed.
	* sysdeps/unix/inet/socket.S: File removed.
	* sysdeps/unix/inet/socketpair.S: File removed.
	* sysdeps/unix/mman/madvise.S: File removed.
	* sysdeps/unix/mman/mmap.S: File removed.
	* sysdeps/unix/mman/mprotect.S: File removed.
	* sysdeps/unix/mman/msync.S: File removed.
	* sysdeps/unix/mman/munmap.S: File removed.
	* sysdeps/unix/sysv/alarm.S: File removed.
	* sysdeps/unix/sysv/ftime.S: File removed.
	* sysdeps/unix/sysv/nice.S: File removed.
	* sysdeps/unix/sysv/pause.S: File removed.
	* sysdeps/unix/sysv/poll.S: File removed.
	* sysdeps/unix/sysv/s_getdents.S: File removed.
	* sysdeps/unix/sysv/signal.S: File removed.
	* sysdeps/unix/sysv/stime.S: File removed.
	* sysdeps/unix/sysv/time.S: File removed.
	* sysdeps/unix/sysv/times.S: File removed.
	* sysdeps/unix/sysv/ulimit.S: File removed.
	* sysdeps/unix/sysv/uname.S: File removed.
	* sysdeps/unix/sysv/utime.S: File removed.
	* sysdeps/unix/sysv/irix4/getpgid.S: File removed.
	* sysdeps/unix/sysv/irix4/msync.S: File removed.
	* sysdeps/unix/sysv/irix4/setpgid.S: File removed.
	* sysdeps/unix/sysv/irix4/signal.S: File removed.
	* sysdeps/unix/sysv/irix4/sysmp.S: File removed.
	* sysdeps/unix/sysv/irix4/syssgi.S: File removed.
	* sysdeps/unix/sysv/isc2.2/rename.S: File removed.
	* sysdeps/unix/sysv/linux/adjtimex.S: File removed.
	* sysdeps/unix/sysv/linux/fork.S: File removed.
	* sysdeps/unix/sysv/linux/getpgid.S: File removed.
	* sysdeps/unix/sysv/linux/getpgrp.S: File removed.
	* sysdeps/unix/sysv/linux/getsid.S: File removed.
	* sysdeps/unix/sysv/linux/gtty.S: File removed.
	* sysdeps/unix/sysv/linux/mlock.S: File removed.
	* sysdeps/unix/sysv/linux/mlockall.S: File removed.
	* sysdeps/unix/sysv/linux/mount.S: File removed.
	* sysdeps/unix/sysv/linux/munlock.S: File removed.
	* sysdeps/unix/sysv/linux/munlockall.S: File removed.
	* sysdeps/unix/sysv/linux/pipe.S: File removed.
	* sysdeps/unix/sysv/linux/s_ptrace.S: File removed.
	* sysdeps/unix/sysv/linux/setpgid.S: File removed.
	* sysdeps/unix/sysv/linux/setsid.S: File removed.
	* sysdeps/unix/sysv/linux/settimeofday.S: File removed.
	* sysdeps/unix/sysv/linux/sigpending.S: File removed.
	* sysdeps/unix/sysv/linux/stty.S: File removed.
	* sysdeps/unix/sysv/linux/umount.S: File removed.
	* sysdeps/unix/sysv/linux/wait4.S: File removed.
	* sysdeps/unix/sysv/linux/i386/ipc.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/pathconf.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/pgrpsys.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sco_getgrp.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sigpending.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sigprocmask.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sigsuspend.S: File removed.
	* sysdeps/unix/sysv/sysv4/pgrpsys.S: File removed.
	* sysdeps/unix/sysv/sysv4/sigprocmask.S: File removed.
	* sysdeps/unix/sysv/sysv4/sigsuspend.S: File removed.
	* sysdeps/unix/sysv/sysv4/sysconfig.S: File removed.
	* sysdeps/unix/sysv/sysv4/sysinfo.S: File removed.
	* sysdeps/unix/sysv/sysv4/solaris2/sparc/sys-sig.S: File removed.
	Replaced all simple system call files *.S throughout sysdeps/unix
	with syscalls.list files to be processed by make-syscalls.sh.
	* sysdeps/unix/s-proto.S: New file.
	* sysdeps/unix/syscalls.list: New file.
	* sysdeps/unix/bsd/syscalls.list: New file.
	* sysdeps/unix/bsd/bsd4.4/syscalls.list: New file.
	* sysdeps/unix/bsd/hp/m68k/syscalls.list: New file.
	* sysdeps/unix/bsd/osf/syscalls.list: New file.
	* sysdeps/unix/bsd/osf/alpha/syscalls.list: New file.
	* sysdeps/unix/bsd/sony/newsos4/syscalls.list: New file.
	* sysdeps/unix/bsd/sun/syscalls.list: New file.
	* sysdeps/unix/bsd/sun/sunos4/syscalls.list: New file.
	* sysdeps/unix/bsd/ultrix4/syscalls.list: New file.
	* sysdeps/unix/common/syscalls.list: New file.
	* sysdeps/unix/inet/syscalls.list: New file.
	* sysdeps/unix/mman/syscalls.list: New file.
	* sysdeps/unix/sysv/syscalls.list: New file.
	* sysdeps/unix/sysv/irix4/syscalls.list: New file.
	* sysdeps/unix/sysv/isc2.2/syscalls.list: New file.
	* sysdeps/unix/sysv/linux/syscalls.list: New file.
	* sysdeps/unix/sysv/linux/i386/syscalls.list: New file.
	* sysdeps/unix/sysv/sco3.2.4/syscalls.list: New file.
	* sysdeps/unix/sysv/sysv4/syscalls.list: New file.
	* sysdeps/unix/sysv/sysv4/i386/syscalls.list: New file.
	* sysdeps/unix/sysv/sysv4/solaris2/sparc/syscalls.list: New file.
	* sysdeps/unix/acct.S: File removed.
	* sysdeps/unix/chdir.S: File removed.
	* sysdeps/unix/chmod.S: File removed.
	* sysdeps/unix/chown.S: File removed.
	* sysdeps/unix/chroot.S: File removed.
	* sysdeps/unix/close.S: File removed.
	* sysdeps/unix/configure: File removed.
	* sysdeps/unix/configure.in: File removed.
	* sysdeps/unix/dup.S: File removed.
	* sysdeps/unix/fcntl.S: File removed.
	* sysdeps/unix/fsync.S: File removed.
	* sysdeps/unix/getgid.S: File removed.
	* sysdeps/unix/getpid.S: File removed.
	* sysdeps/unix/getuid.S: File removed.
	* sysdeps/unix/ioctl.S: File removed.
	* sysdeps/unix/kill.S: File removed.
	* sysdeps/unix/link.S: File removed.
	* sysdeps/unix/lseek.S: File removed.
	* sysdeps/unix/open.S: File removed.
	* sysdeps/unix/ptrace.S: File removed.
	* sysdeps/unix/read.S: File removed.
	* sysdeps/unix/reboot.S: File removed.
	* sysdeps/unix/setgid.S: File removed.
	* sysdeps/unix/setuid.S: File removed.
	* sysdeps/unix/sync.S: File removed.
	* sysdeps/unix/umask.S: File removed.
	* sysdeps/unix/unlink.S: File removed.
	* sysdeps/unix/write.S: File removed.
	* sysdeps/unix/bsd/flock.S: File removed.
	* sysdeps/unix/bsd/getdtsz.S: File removed.
	* sysdeps/unix/bsd/getpagesize.S: File removed.
	* sysdeps/unix/bsd/killpg.S: File removed.
	* sysdeps/unix/bsd/profil.S: File removed.
	* sysdeps/unix/bsd/readv.S: File removed.
	* sysdeps/unix/bsd/settimeofday.S: File removed.
	* sysdeps/unix/bsd/sigblock.S: File removed.
	* sysdeps/unix/bsd/sigpause.S: File removed.
	* sysdeps/unix/bsd/sigsetmask.S: File removed.
	* sysdeps/unix/bsd/sigstack.S: File removed.
	* sysdeps/unix/bsd/sigvec.S: File removed.
	* sysdeps/unix/bsd/utimes.S: File removed.
	* sysdeps/unix/bsd/writev.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/chflags.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/fchdir.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/fchflags.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/getdents.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/getdomain.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/revoke.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setdomain.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setegid.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/seteuid.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setlogin.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/setsid.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/sigaltstack.S: File removed.
	* sysdeps/unix/bsd/bsd4.4/wait4.S: File removed.
	* sysdeps/unix/bsd/hp/m68k/getdents.S: File removed.
	* sysdeps/unix/bsd/osf/msync.S: File removed.
	* sysdeps/unix/bsd/osf/alpha/wait4.S: File removed.
	* sysdeps/unix/bsd/sony/newsos4/fchdir.S: File removed.
	* sysdeps/unix/bsd/sony/newsos4/sys_wait4.S: File removed.
	* sysdeps/unix/bsd/sun/getdents.S: File removed.
	* sysdeps/unix/bsd/sun/sunos3/m68k/wait.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/msync.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/poll.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/setsid.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/sys_mmap.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/sys_wait4.S: File removed.
	* sysdeps/unix/bsd/sun/sunos4/uname.S: File removed.
	* sysdeps/unix/bsd/ultrix4/getdents.S: File removed.
	* sysdeps/unix/bsd/ultrix4/setsid.S: File removed.
	* sysdeps/unix/bsd/ultrix4/uname.S: File removed.
	* sysdeps/unix/common/access.S: File removed.
	* sysdeps/unix/common/adjtime.S: File removed.
	* sysdeps/unix/common/dup2.S: File removed.
	* sysdeps/unix/common/fchmod.S: File removed.
	* sysdeps/unix/common/fchown.S: File removed.
	* sysdeps/unix/common/ftruncate.S: File removed.
	* sysdeps/unix/common/getgroups.S: File removed.
	* sysdeps/unix/common/getitimer.S: File removed.
	* sysdeps/unix/common/getpgid.S: File removed.
	* sysdeps/unix/common/getpriority.S: File removed.
	* sysdeps/unix/common/getrlimit.S: File removed.
	* sysdeps/unix/common/getrusage.S: File removed.
	* sysdeps/unix/common/gettimeofday.S: File removed.
	* sysdeps/unix/common/mkdir.S: File removed.
	* sysdeps/unix/common/readlink.S: File removed.
	* sysdeps/unix/common/rename.S: File removed.
	* sysdeps/unix/common/rmdir.S: File removed.
	* sysdeps/unix/common/select.S: File removed.
	* sysdeps/unix/common/setgroups.S: File removed.
	* sysdeps/unix/common/setitimer.S: File removed.
	* sysdeps/unix/common/setpgid.S: File removed.
	* sysdeps/unix/common/setpriority.S: File removed.
	* sysdeps/unix/common/setregid.S: File removed.
	* sysdeps/unix/common/setreuid.S: File removed.
	* sysdeps/unix/common/setrlimit.S: File removed.
	* sysdeps/unix/common/swapon.S: File removed.
	* sysdeps/unix/common/symlink.S: File removed.
	* sysdeps/unix/common/truncate.S: File removed.
	* sysdeps/unix/common/vhangup.S: File removed.
	* sysdeps/unix/inet/accept.S: File removed.
	* sysdeps/unix/inet/bind.S: File removed.
	* sysdeps/unix/inet/connect.S: File removed.
	* sysdeps/unix/inet/gethostid.S: File removed.
	* sysdeps/unix/inet/gethostname.S: File removed.
	* sysdeps/unix/inet/getpeername.S: File removed.
	* sysdeps/unix/inet/getsockname.S: File removed.
	* sysdeps/unix/inet/getsockopt.S: File removed.
	* sysdeps/unix/inet/listen.S: File removed.
	* sysdeps/unix/inet/recv.S: File removed.
	* sysdeps/unix/inet/recvfrom.S: File removed.
	* sysdeps/unix/inet/recvmsg.S: File removed.
	* sysdeps/unix/inet/send.S: File removed.
	* sysdeps/unix/inet/sendmsg.S: File removed.
	* sysdeps/unix/inet/sendto.S: File removed.
	* sysdeps/unix/inet/sethostid.S: File removed.
	* sysdeps/unix/inet/sethostname.S: File removed.
	* sysdeps/unix/inet/setsockopt.S: File removed.
	* sysdeps/unix/inet/shutdown.S: File removed.
	* sysdeps/unix/inet/socket.S: File removed.
	* sysdeps/unix/inet/socketpair.S: File removed.
	* sysdeps/unix/mman/madvise.S: File removed.
	* sysdeps/unix/mman/mmap.S: File removed.
	* sysdeps/unix/mman/mprotect.S: File removed.
	* sysdeps/unix/mman/msync.S: File removed.
	* sysdeps/unix/mman/munmap.S: File removed.
	* sysdeps/unix/sysv/alarm.S: File removed.
	* sysdeps/unix/sysv/ftime.S: File removed.
	* sysdeps/unix/sysv/nice.S: File removed.
	* sysdeps/unix/sysv/pause.S: File removed.
	* sysdeps/unix/sysv/poll.S: File removed.
	* sysdeps/unix/sysv/s_getdents.S: File removed.
	* sysdeps/unix/sysv/signal.S: File removed.
	* sysdeps/unix/sysv/stime.S: File removed.
	* sysdeps/unix/sysv/time.S: File removed.
	* sysdeps/unix/sysv/times.S: File removed.
	* sysdeps/unix/sysv/ulimit.S: File removed.
	* sysdeps/unix/sysv/uname.S: File removed.
	* sysdeps/unix/sysv/utime.S: File removed.
	* sysdeps/unix/sysv/irix4/getpgid.S: File removed.
	* sysdeps/unix/sysv/irix4/msync.S: File removed.
	* sysdeps/unix/sysv/irix4/setpgid.S: File removed.
	* sysdeps/unix/sysv/irix4/signal.S: File removed.
	* sysdeps/unix/sysv/irix4/sysmp.S: File removed.
	* sysdeps/unix/sysv/irix4/syssgi.S: File removed.
	* sysdeps/unix/sysv/isc2.2/rename.S: File removed.
	* sysdeps/unix/sysv/linux/adjtimex.S: File removed.
	* sysdeps/unix/sysv/linux/fork.S: File removed.
	* sysdeps/unix/sysv/linux/getpgid.S: File removed.
	* sysdeps/unix/sysv/linux/getpgrp.S: File removed.
	* sysdeps/unix/sysv/linux/getsid.S: File removed.
	* sysdeps/unix/sysv/linux/gtty.S: File removed.
	* sysdeps/unix/sysv/linux/mlock.S: File removed.
	* sysdeps/unix/sysv/linux/mlockall.S: File removed.
	* sysdeps/unix/sysv/linux/mount.S: File removed.
	* sysdeps/unix/sysv/linux/munlock.S: File removed.
	* sysdeps/unix/sysv/linux/munlockall.S: File removed.
	* sysdeps/unix/sysv/linux/pipe.S: File removed.
	* sysdeps/unix/sysv/linux/s_ptrace.S: File removed.
	* sysdeps/unix/sysv/linux/setpgid.S: File removed.
	* sysdeps/unix/sysv/linux/setsid.S: File removed.
	* sysdeps/unix/sysv/linux/settimeofday.S: File removed.
	* sysdeps/unix/sysv/linux/sigpending.S: File removed.
	* sysdeps/unix/sysv/linux/stty.S: File removed.
	* sysdeps/unix/sysv/linux/umount.S: File removed.
	* sysdeps/unix/sysv/linux/wait4.S: File removed.
	* sysdeps/unix/sysv/linux/i386/ipc.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/pathconf.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/pgrpsys.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sco_getgrp.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sigpending.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sigprocmask.S: File removed.
	* sysdeps/unix/sysv/sco3.2.4/sigsuspend.S: File removed.
	* sysdeps/unix/sysv/sysv4/pgrpsys.S: File removed.
	* sysdeps/unix/sysv/sysv4/sigprocmask.S: File removed.
	* sysdeps/unix/sysv/sysv4/sigsuspend.S: File removed.
	* sysdeps/unix/sysv/sysv4/sysconfig.S: File removed.
	* sysdeps/unix/sysv/sysv4/sysinfo.S: File removed.
	* sysdeps/unix/sysv/sysv4/solaris2/sparc/sys-sig.S: File removed.

	* io/mknod.c: New file.
1996-01-19 00:42:21 +00:00
Roland McGrath aeb72b1622 Thu Jan 18 00:32:43 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* Makerules (COMPILE.s): New variable.

	* sysdeps/unix/Makefile (sysd-syscalls): New target; generate with
	make-syscalls.sh and include it.
	[$(subdir)=misc] (sysdep_routines): Append extra syscalls from
	sysd-syscalls.
	* sysdeps/unix/make-syscalls.sh: New file.

	* Makerules (COMPILE.S): New variable.
1996-01-18 10:00:52 +00:00
Roland McGrath 285a3eee46 * sysdeps/unix/sysv/linux/statbuf.h (_STAT_VER_LINUX,
_STAT_VER_SVR4, _STAT_VER): New macros.
	(_MKNOD_VER_LINUX, _MKNOD_VER_SVR4, _MKNOD_VER): New macros.

	* sysdeps/unix/sysv/sysv4/i386/statbuf.h (_STAT_VER, _MKNOD_VER):
	New macros.
1996-01-18 00:50:52 +00:00
Roland McGrath c43b8c4bea Wed Jan 17 11:04:58 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* io/sys/stat.h (_STAT_VER, _MKNOD_VER): New macros.
	(__xstat, __fxstat, __lxstat, __xmknod): Declare new functions.
	[__GNUC__] (stat, fstat, lstat, mknod): Define these (and __ names)
	as `extern inline's calling the `x' functions.
	* io/fstat.c: New file.
	* io/lstat.c: New file.
	* io/stat.c: New file.
	* sysdeps/generic/lstat.c: File removed.
	* sysdeps/generic/lxstat.c: New file.
	* sysdeps/mach/hurd/fstat.c: File removed.
	* sysdeps/mach/hurd/fxstat.c: New file.
	* sysdeps/mach/hurd/lstat.c: File removed.
	* sysdeps/mach/hurd/lxstat.c: New file.
	* sysdeps/mach/hurd/mknod.c: File removed.
	* sysdeps/mach/hurd/stat.c: File removed.
	* sysdeps/mach/hurd/xmknod.c: New file.
	* sysdeps/mach/hurd/xstat.c: New file.
	* sysdeps/stub/fstat.c: File removed.
	* sysdeps/stub/fxstat.c: New file.
	* sysdeps/stub/lstat.c: File removed.
	* sysdeps/stub/lxstat.c: New file.
	* sysdeps/stub/mknod.c: File removed.
	* sysdeps/stub/stat.c: File removed.
	* sysdeps/stub/xmknod.c: New file.
	* sysdeps/stub/xstat.c: New file.
	* sysdeps/unix/common/lstat.S: File removed.
	* sysdeps/unix/common/lxstat.c: New file.
	* sysdeps/unix/fstat.S: File removed.
	* sysdeps/unix/fxstat.c: New file.
	* sysdeps/unix/mknod.S: File removed.
	* sysdeps/unix/stat.S: File removed.
	* sysdeps/unix/sysv/linux/fstat.c: File removed.
	* sysdeps/unix/sysv/linux/i386/fxstat.S: File removed.
	* sysdeps/unix/sysv/linux/i386/lxstat.S: File removed.
	* sysdeps/unix/sysv/linux/i386/xmknod.S: File removed.
	* sysdeps/unix/sysv/linux/i386/xstat.S: File removed.
	* sysdeps/unix/sysv/linux/lstat.c: File removed.
	* sysdeps/unix/sysv/linux/mknod.c: File removed.
	* sysdeps/unix/sysv/linux/stat.c: File removed.
	* sysdeps/unix/sysv/sysv4/i386/fstat.S: File removed.
	* sysdeps/unix/sysv/sysv4/i386/lstat.S: File removed.
	* sysdeps/unix/sysv/sysv4/i386/mknod.S: File removed.
	* sysdeps/unix/sysv/sysv4/i386/stat.S: File removed.
	* sysdeps/unix/xmknod.c: New file.
	* sysdeps/unix/xstat.c: New file.
	* sysdeps/unix/mkfifo.c: Use __xmknod instead of __mknod.
	* misc/Makefile (routines): Remove mknod.
	* io/sys/stat.h (_STAT_VER, _MKNOD_VER): New macros.
	(__xstat, __fxstat, __lxstat, __xmknod): Declare new functions.
	[__GNUC__] (stat, fstat, lstat, mknod): Define these (and __ names)
	as `extern inline's calling the `x' functions.
	* io/fstat.c: New file.
	* io/lstat.c: New file.
	* io/stat.c: New file.
	* sysdeps/generic/lstat.c: File removed.
	* sysdeps/generic/lxstat.c: New file.
	* sysdeps/mach/hurd/fstat.c: File removed.
	* sysdeps/mach/hurd/fxstat.c: New file.
	* sysdeps/mach/hurd/lstat.c: File removed.
	* sysdeps/mach/hurd/lxstat.c: New file.
	* sysdeps/mach/hurd/mknod.c: File removed.
	* sysdeps/mach/hurd/stat.c: File removed.
	* sysdeps/mach/hurd/xmknod.c: New file.
	* sysdeps/mach/hurd/xstat.c: New file.
	* sysdeps/stub/fstat.c: File removed.
	* sysdeps/stub/fxstat.c: New file.
	* sysdeps/stub/lstat.c: File removed.
	* sysdeps/stub/lxstat.c: New file.
	* sysdeps/stub/mknod.c: File removed.
	* sysdeps/stub/stat.c: File removed.
	* sysdeps/stub/xmknod.c: New file.
	* sysdeps/stub/xstat.c: New file.
	* sysdeps/unix/common/lstat.S: File removed.
	* sysdeps/unix/common/lxstat.c: New file.
	* sysdeps/unix/fstat.S: File removed.
	* sysdeps/unix/fxstat.c: New file.
	* sysdeps/unix/mknod.S: File removed.
	* sysdeps/unix/stat.S: File removed.
	* sysdeps/unix/sysv/linux/fstat.c: File removed.
	* sysdeps/unix/sysv/linux/i386/fxstat.S: File removed.
	* sysdeps/unix/sysv/linux/i386/lxstat.S: File removed.
	* sysdeps/unix/sysv/linux/i386/xmknod.S: File removed.
	* sysdeps/unix/sysv/linux/i386/xstat.S: File removed.
	* sysdeps/unix/sysv/linux/lstat.c: File removed.
	* sysdeps/unix/sysv/linux/mknod.c: File removed.
	* sysdeps/unix/sysv/linux/stat.c: File removed.
	* sysdeps/unix/sysv/sysv4/i386/fstat.S: File removed.
	* sysdeps/unix/sysv/sysv4/i386/lstat.S: File removed.
	* sysdeps/unix/sysv/sysv4/i386/mknod.S: File removed.
	* sysdeps/unix/sysv/sysv4/i386/stat.S: File removed.
	* sysdeps/unix/xmknod.c: New file.
	* sysdeps/unix/xstat.c: New file.
	* sysdeps/unix/mkfifo.c: Use __xmknod instead of __mknod.
	* misc/Makefile (routines): Remove mknod.

	* sysdeps/ieee754/ieee754.h (union ieee854_long_double.ieee_nan):
	Add missing ; in little-endian case.
1996-01-18 00:35:55 +00:00
Roland McGrath c59928df4d (_STAT_VER, _MKNOD_VER): New macros. (__xstat, __fxstat, __lxstat, __xmknod): Declare new functions. [__GNUC__] (stat, fstat, lstat, mknod): Define these (and __ names) as extern inline's calling the x' functions. 1996-01-18 00:10:56 +00:00
Doug Evans af8488a871 Recognize go32* as an os. 1996-01-17 23:54:58 +00:00
Richard M. Stallman bc8789b942 Default OS to nextstep if machine vendor is Next. -ns2 is an alias for -nextstep. 1996-01-17 22:40:42 +00:00
Roland McGrath 069aa63891 (union ieee854_long_double.ieee_nan): Add missing ; in little-endian case. 1996-01-17 22:33:48 +00:00
Roland McGrath 44534645d6 * elf/dynamic-link.h [ELF_MACHINE_NO_REL] (ELF_DYNAMIC_DO_REL):
Define this instead of ELF_DYNAMIC_DO_RELA.
1996-01-17 17:42:14 +00:00
Roland McGrath 9399579574 Sun Jan 14 01:01:10 1996 Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
* sysdeps/mips/bytesex.h: Add default byte sex.  By Ralf Baechle.

	* sysdeps/unix/sysv/linux/adjtime.c [! MOD_OFFSET]: Use `mode'
	member of `struct timex' instead of `modes'.  From Andreas Schwab.

	* sysdeps/unix/sysv/linux/mknod.c: New file.  Generic C version.
	* sysdeps/unix/sysv/linux/i386/mknod.S: Remove assembler version.

	* sysdeps/unix/sysv/linux/Makefile (inhibit-glue): New variable.
	[$(subdir) = misc] (sysdep_routines): Add mount, umount, and s_ptrace.
	[$(subdir) = misc] (headers): Append sys/mount.h.

	* sysdeps/unix/sysv/linux/mount.S, sysdeps/unix/sysv/linux/umount.S:
	New files.  Implement system calls.
	* sysdeps/unix/sysv/linux/sys/mount.h: New header file.

	* sysdeps/unix/sysv/linux/ptrace.c: New file.  Wrapper around
	ptrace system call.
	* sysdeps/unix/sysv/linux/s_ptrace.S: New file: ptrace system call.

	* sysdeps/unix/sysv/linux/i386/gnu/types.h: New file with correct
	types for i386/Linux.
Sun Jan 14 01:01:10 1996  Ulrich Drepper  <drepper@ipd.info.uni-karlsruhe.de>

	* sysdeps/mips/bytesex.h: Add default byte sex.  By Ralf Baechle.

	* sysdeps/unix/sysv/linux/adjtime.c [! MOD_OFFSET]: Use `mode'
	member of `struct timex' instead of `modes'.  From Andreas Schwab.

	* sysdeps/unix/sysv/linux/mknod.c: New file.  Generic C version.
	* sysdeps/unix/sysv/linux/i386/mknod.S: Remove assembler version.

	* sysdeps/unix/sysv/linux/Makefile (inhibit-glue): New variable.
	[$(subdir) = misc] (sysdep_routines): Add mount, umount, and s_ptrace.
	[$(subdir) = misc] (headers): Append sys/mount.h.

	* sysdeps/unix/sysv/linux/mount.S, sysdeps/unix/sysv/linux/umount.S:
	New files.  Implement system calls.
	* sysdeps/unix/sysv/linux/sys/mount.h: New header file.

	* sysdeps/unix/sysv/linux/ptrace.c: New file.  Wrapper around
	ptrace system call.
	* sysdeps/unix/sysv/linux/s_ptrace.S: New file: ptrace system call.

	* sysdeps/unix/sysv/linux/i386/gnu/types.h: New file with correct
	types for i386/Linux.
1996-01-17 17:13:48 +00:00
Roland McGrath 6f0017d1cd Wed Jan 17 11:04:58 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/sysv/time.S: Moved from sysv4.
	* sysdeps/unix/sysv/irix4/time.S: File removed.

	* sysdeps/unix/sysv/linux/signum.h: Moved from
	sysdeps/unix/sysv/linux/i386.
	(_NSIG): Move inside #ifdef _SIGNAL_H.
Wed Jan 17 11:04:58 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* sysdeps/unix/sysv/time.S: Moved from sysv4.
	* sysdeps/unix/sysv/irix4/time.S: File removed.

	* sysdeps/unix/sysv/linux/signum.h: Moved from
	sysdeps/unix/sysv/linux/i386.
	(_NSIG): Move inside #ifdef _SIGNAL_H.
1996-01-17 16:17:58 +00:00
Roland McGrath b6e9b25ba8 * sysdeps/unix/seekdir.c: Don't modify POS before seeking.
* sysdeps/unix/telldir.c: Fix position calculation to account for
	buffered data properly.
1996-01-17 10:00:23 +00:00
Roland McGrath b8aec9fa1a Sun Jan 14 17:51:09 1996 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* MakeTAGS (all-sources, all-headers): Always search the
	current directory first.

	* db/btree/bt_seq.c (__bt_first): Return RET_SPECIAL when key not
	found.
	* MakeTAGS (all-sources, all-headers): Always search the
	current directory first.

	* db/btree/bt_seq.c (__bt_first): Return RET_SPECIAL when key not
	found.
1996-01-17 02:41:04 +00:00
Roland McGrath 13bc775dc3 * sysdeps/m68k/Makefile (crypt): Don't define if building a shared
library.
1996-01-17 02:33:33 +00:00
Roland McGrath 5f3d5c2bbb * csu/initfini.c (_init): Call __gmon_start__ if defined (weak ref).
* csu/gmon-start.c (__gmon_start__): Renamed from gmon_start, made
	global.
	[! HAVE_INITFINI]: Only make it a constructor in this case.
1996-01-17 02:29:57 +00:00
Roland McGrath d99d7e2644 * gmon/Makefile (CFLAGS-mcount.c): New variable.
(mcount.po): New target.

	* Makeconfig (CFLAGS): Append $(CFLAGS-$(<F)).
1996-01-17 02:11:06 +00:00
Roland McGrath 7176f4e4b5 * misc/efgcvt_r.c (ecvt_r): Handle negative values.
* stdlib/stdlib.h: Replace __CONSTVALUE by attribute.
	* stdlib/abs.c, stdlib/div.c, stdlib/labs.c, stdlib/ldiv.c,
	sysdeps/generic/hypot.c: Remove obsolete __CONSTVALUE.

	* stdio-common/printf_fp.c (__printf_fp): Fix parameter
	declaration.

	* sysdeps/generic/putenv.c (putenv): Fix second argument of
	setenv.

	* sysdeps/ieee754/hypot.c: New file, extracted out of cabs.c.
	* sysdeps/ieee754/cabs.c: Don't define hypot here.

	* sysdeps/ieee754/ieee754.h (union ieee854_long_double): Fix
	definition of ieee_nan alternative.

	* sysdeps/m68k/__longjmp.c, sysdeps/m68k/setjmp.c: Add register
 	prefix spec.

	* sysdeps/m68k/ffs.c (ffs): Fix register constraint.

	* sysdeps/m68k/fpu/__math.h: Include <errno.h>.  Replace obsolete
	__CONSTVALUE by attribute.
	(floor): Round to negative infinity.
	(rint, expm1) [__NO_MATH_INLINES]: Don't define, to avoid type
	clash when compiling source.
	(pow): Handle x == 0 and x < 0.
	(ceil, __isinf, __isnan): Fix register constraints.
	(__isinfl, __isnanl): Added.
	* sysdeps/m68k/fpu/acos.c, sysdeps/m68k/fpu/atan2.c,
	sysdeps/m68k/fpu/fmod.c, sysdeps/m68k/fpu/ldexp.c,
	sysdeps/m68k/fpu/pow.c: Remove obsolete __CONSTVALUE.

	* sysdeps/m68k/bsd-_setjmp.S, sysdeps/m68k/bsd-setjmp.S: Fix
	assembler syntax.

	* sysdeps/unix/bsd/bsd4.4/fchdir.S (fchdir): Take only one
 	argument.

	* sysdeps/unix/bsd/clock.c (timeval_to_clock_t): Fix timeval to
	clock_t conversion.
	(clock): Don't multiply by CLOCKS_PER_SEC.

	* sysdeps/unix/bsd/poll.c (poll): Fix msec to timeval conversion.

	* sysdeps/unix/bsd/sun/m68k/brk.S (brk): Compare with address of
	__end.

	* sysdeps/unix/bsd/sun/m68k/vfork.S: Fix assembler syntax.

	* sysdeps/unix/bsd/ualarm.c (ualarm): Fix timeval calculation.

	* sysdeps/unix/bsd/vax/vfork.S: Remove duplicate label.
1996-01-17 02:03:00 +00:00
Roland McGrath b17178fc56 Tue Jan 16 17:37:39 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* csu/Makefile [have-initfini=yes] (CPPFLAGS): Append -DHAVE_INITFINI.
	(initfini): Compile initfini.c with -fPIC.

Sun Jan 14 17:51:09 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* stdio-common/vfscanf.c (inchar, conv_error, input_error,
	memory_error): Add cast to void to avoid gcc warning.
	(vfscanf): Rewrite character class parsing to make it more efficient.
1996-01-17 01:46:13 +00:00
Roland McGrath da128169aa Sun Jan 14 01:01:10 1996 Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
* stdlib/strtol.c: Return correct pointer for strings
	like "0xyz" and base 0 or 16.

	* string/strxfrm.c: Handle case for LENGTH == 0 correct.

	* sunrpc/etc.rpc: Add some more known protocols.
Sun Jan 14 01:01:10 1996  Ulrich Drepper  <drepper@ipd.info.uni-karlsruhe.de>

	* stdlib/strtol.c: Return correct pointer for strings
	like "0xyz" and base 0 or 16.

	* string/strxfrm.c: Handle case for LENGTH == 0 correct.

	* sunrpc/etc.rpc: Add some more known protocols.
1996-01-17 00:46:59 +00:00
Roland McGrath 294897f4a6 [have-initfini=yes] (CPPFLAGS): Append -DHAVE_INITFINI. (initfini): Compile initfini.c with -fPIC. 1996-01-16 22:37:27 +00:00
Richard Kenner d008bcf32c (sco5): New case. 1996-01-16 01:58:43 +00:00
Roland McGrath 4984f343aa . 1996-01-14 10:00:22 +00:00
Roland McGrath 02ac66c50d Fri Jan 12 13:40:01 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* posix/gnu/types.h: Moved to sysdeps/generic/gnu/types.h.

	* posix/glob.c (glob): Add parens in glob call flags arg for
	GLOB_BRACE case.

	* string/string.h (strdupa): New macro.

	* stdio-common/vfscanf.c (%[): Grok ] as first char in set, not
	terminator on empty set.  From drepper.
1996-01-13 00:46:48 +00:00
Roland McGrath d94d8f2a59 Thu Jan 11 13:09:20 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/do-rel.h (elf_dynamic_do_rel): Use referring symbol as
	referent for STB_LOCAL.
1996-01-11 18:09:50 +00:00
Roland McGrath 72d8cdf09d Wed Jan 10 10:11:39 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* time/africa, time/antarctica, time/asia, time/australasia,
 	time/europe, time/northamerica, time/pacificnew, time/solar87,
 	time/solar88, time/solar89, time/southamerica: Updated from ADO 96a.
1996-01-11 10:00:22 +00:00
Roland McGrath 22930c9bf2 Tue Jan 9 16:10:26 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/dl-load.c (_dl_map_object_from_fd): After mapping first
 	segment to find location, mprotect excess region to no access,
 	don't munmap it.

	* sysdeps/mach/hurd/dl-sysdep.c (mmap): If vm_map returns
	KERN_NO_SPACE for fixed location, deallocate it and try again.
1996-01-10 10:00:22 +00:00
Roland McGrath 7410183b8b Mon Jan 8 17:43:23 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* locale/Makefile (lib-modules): Renamed hash to locfile-hash.
	* locale/hash.c: Renamed to locale/locfile-hash.c.
1996-01-09 10:00:21 +00:00
Roland McGrath 02859f472b Thu Dec 14 02:28:22 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* posix/glob.c (glob_in_dir): Cast result of opendir to __ptr_t,
	and cast STREAM to DIR * before passing to readdir and closedir.
1996-01-08 22:44:45 +00:00
Roland McGrath a2e1b046f6 Sat Jan 6 16:39:14 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* Makefile (subdirs): Added db.

	* resolv/Makefile (routines): Add res_data.
	* resolv/res_data.c, resolv/res_debug.c, resolv/resolv.h:
	Updated from BIND 4.9.3 final release.

	* elf/dynamic-link.h (elf_get_dynamic_info): Handle
	processor-specific tags.
	(ELF_DYNAMIC_DO_REL, ELF_DYNAMIC_DO_RELA): Handle absent DT_PLTREL tag.

	* elf/elf.h (DT_MIPS_NUM, DT_PROCNUM): New macros.
	* elf/link.h (struct link_map): Extend `l_info' by DT_PROCNUM.

	* sysdeps/i386/dl-machine.h (elf_machine_runtime_setup): Take new
	arg LAZY.  Only do our work if LAZY and there is a DT_JMPREL record.
	* elf/dl-reloc.c (_dl_relocate_object): Call
	elf_machine_runtime_setup unconditionally, and pass it LAZY flag.

	* elf/dl-load.c: Fixed ELFMAG check to work for either byte order.
	Align end of load segment only to page size, not to segment alignment.
1996-01-07 10:00:21 +00:00
Roland McGrath c4b7291877 Fixed ELFMAG check to work for either byte order. Align end of load segment only to page size, not to segment alignment. 1996-01-06 21:39:03 +00:00
Jim Meyering 85f4084001 Reverse order of arguments in getgroups call (in example) to match prototype. 1996-01-04 23:21:47 +00:00
Roland McGrath 7974fe2117 Thu Jan 4 11:35:18 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/setitimer.c: Code rearranged a bit to use new
	preemption interface.

	* sysdeps/mach/hurd/i386/trampoline.c (_hurd_setup_sighandler):
	Use _hurdsig_catch_memory_fault.

	* hurd/Makefile (headers): Add hurd/sigpreempt.h.
	(sig): Add catch-signal.

	* hurd/hurdfault.c (_hurdsig_fault_catch_exception_raise):
	Rewritten using a preempter in new interface.
	* hurd/hurdfault.h (_hurdsig_catch_fault): Likewise.
	(_hurdsig_catch_memory_fault): New macro.
1996-01-04 17:00:45 +00:00
Roland McGrath fb8e70d6dd Wed Jan 3 20:23:42 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* hurd/catch-signal.c: New file.

	* hurd/intr-msg.c: When restarting RPC, fetch a new reply port.

	* hurd/hurdsig.c: Use new hurdfault.h interface.
	(abort_all_rpcs): Mutate return value to EINTR in threads whose
	replies we will wait for.

	* hurd/hurdkill.c (_hurd_sig_post): When doing pgrp, make sure we
	do ourselves last.

Wed Jan  3 19:17:10 1996  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/access.c (__access): Put the uid/gid arguments
	to auth_makeauth() in the right order.

Wed Jan  3 17:19:04 1996  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* sysdeps/generic/strsep.c: Rewritten.

	* sysdeps/mach/hurd/fork.c: Use a different workaround for the
 	suspended page fault deadlock kernel bug: thread_abort our signal
 	thread first thing after proc_dostop.

	* sysdeps/mach/hurd/setgid.c: Rewrote gid frobnication to
	recognize rootness properly.

	* hurd/hurdsig.c: Use new signal preemption interface.
1996-01-04 10:00:22 +00:00
Roland McGrath 67f27f3a02 (_hurd_sig_post): When doing pgrp, make sure we do ourselves last. 1996-01-04 01:23:21 +00:00
Miles Bader 9418ccede9 (__access): Put the uid/gid arguments to auth_makeauth() in the right order. 1996-01-04 00:18:53 +00:00
Roland McGrath 6df1b2474a Rewritten. 1996-01-04 00:06:01 +00:00
Roland McGrath 71733723fb * hurd/hurd/signal.h (struct hurd_sigstate): New member `preempters'.
(hurd_preempt_signals, hurd_unpreempt_signals): Decls removed.
	* hurd/hurd/sigpreempt.h: New file.
	* hurd/preempt-sig.c: Rewritten with new interface.
	* sysdeps/mach/hurd/jmp-unwind.c (_longjmp_unwind): Remove local signal
	preempters being unwound past.

	* db: New directory, 4.4 BSD db package incorporated from BSD db-1.85
	release.

	* sysdeps/unix/sysv/linux/sys/param.h: Several new macros for BSD
	compatibility.
1996-01-02 08:57:42 +00:00
Roland McGrath fc4026d8e4 Tue Jan 2 00:50:10 1996 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* misc/queue.h: New file, incorporated from 4.4BSD.
	* misc/Makefile (headers): Add queue.h.

	* posix/sys/types.h [__USE_BSD]: Include endian.h.

	* io/sys/stat.h (DEFFILEMODE, ALLPERMS, ACCESSPERMS, S_BLKSIZE):
	New macros.
1996-01-02 06:19:15 +00:00
Roland McGrath 0a95f04d06 Thu Dec 28 10:21:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/generic/confname.h: Define all names as self-referential
	macros so #ifdef works.

	* hurd/preempt-sig.c (hurd_unpreempt_signals): Remove bogus asgnmt
	of _hurd_signal_preempters[SIGNO].
1995-12-29 10:00:22 +00:00
Roland McGrath be7e3b7e7e Mon Dec 25 20:56:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/bind.c: Translate EEXIST from dir_link into
	EADDRINUSE.  If translated node doesn't grok ifsock protocol,
	return EADDRINUSE.

	* sysdeps/mach/hurd/connect.c: Make address arg
	`const struct sockaddr_un *'.
	The redecl is kosher and avoids another variable for AF_LOCAL case.
	* sysdeps/mach/hurd/sendto.c: Likewise.
	* sysdeps/mach/hurd/bind.c: Likewise.

	* socket/sys/socket.h (__SOCKADDR_ARG): Enable transparent_union
 	code for GCC >= 2.7; use __transparent_union__ for name safety;
 	add several sockaddr flavors.
	(__SOCKADDR_ALLTYPES, __SOCKADDR_ONETYPE): New macros used in
	constructing the transparent union declarations.
	(__CONST_SOCKADDR_ARG): New type (or macro if not GCC 2.7).
	(bind, connect, sendto): Make the sockaddr argument use that.
1995-12-26 10:00:22 +00:00
Roland McGrath e0f09b6b2a * sysdeps/mach/hurd/setgid.c: In root case, store into NEWAUX, not
old vector.
	* sysdeps/mach/hurd/setuid.c: Likewise.
1995-12-23 01:16:45 +00:00
Roland McGrath 2114e10acb Fri Dec 22 00:38:00 1995 H.J. Lu <hjl@nynexst.com>
* stdio-common/vfscanf.c: Correctly handle white space skipping.
	* stdio-common/Makefile (tests): Add bug11.
	* stdio-common/bug11.c: New file.
Fri Dec 22 00:38:00 1995  H.J. Lu  <hjl@nynexst.com>

        * stdio-common/vfscanf.c: Correctly handle white space skipping.
	* stdio-common/Makefile (tests): Add bug11.
	* stdio-common/bug11.c: New file.
1995-12-23 01:14:10 +00:00
Roland McGrath 975320984b Fri Dec 22 00:57:38 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/setuid.c: Rewrote ID frobnication to do the
	right thing.
	* sysdeps/mach/hurd/setgid.c: Likewise.
	* sysdeps/mach/hurd/setreuid.c: Likewise.
	* sysdeps/mach/hurd/setregid.c: Likewise.
	* sysdeps/mach/hurd/setegid.c: Likewise.
	* sysdeps/mach/hurd/seteuid.c: Likewise.

	* sysdeps/mach/hurd/fork.c: Peek __mach_task_self_ value before
	proc_dostop call to work around kernel paging bug.

Thu Dec 21 12:19:32 1995  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/setuid.c (__setuid): Actually add the new uid
 	instead of putting it (and other uids) in the gids and leaving the
 	old uids as is.
1995-12-22 10:00:21 +00:00
Roland McGrath e3fa2641f4 Peek __mach_task_self_ value before proc_dostop call to work around kernel paging bug. 1995-12-22 05:57:24 +00:00
Miles Bader 567676ff81 (__setuid): Actually add the new uid instead of putting it (and other uids) in the gids and leaving the old uids as is. 1995-12-21 17:43:59 +00:00
Roland McGrath 8ef76445e8 Wed Dec 20 18:23:10 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* stdio/internals.c (flushbuf): If the target is -1, always
	discard the buffer of read data.
	Only set TWIDDLED flag in !ALIGNED case.
	Never increment target or offset when old value is -1.
1995-12-21 10:00:22 +00:00
Roland McGrath f94a3574d5 Tue Dec 19 17:00:42 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* hurd/hurdpid.c (_S_msg_proc_newids): Only run the hook when the
	pgrp changes.
1995-12-20 10:00:22 +00:00
Roland McGrath 755f55b0db Mon Dec 18 13:40:37 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* stdio/fread.c: Don't increment __offset when it's -1.

	* elf/rtld.c (dl_main): Prepend tab to "statically linked".  Exit
	0 in that case.

	* misc/err.c (vwarnx, vwarn): Fix major brainos.

	* sysdeps/mach/hurd/dl-sysdep.c (mmap): Fix setting of
	inheritance.
1995-12-19 10:00:22 +00:00
Roland McGrath 8882961f38 Sun Dec 17 15:56:35 1995 Miles Bader <miles@gnu.ai.mit.edu>
* misc/getpass.c (getpass): Don't barf if getline returns a null BUF.
1995-12-18 10:00:20 +00:00
Miles Bader 5ca8c0ba63 (getpass): Don't barf if getline returns a null BUF. 1995-12-17 20:58:55 +00:00
Roland McGrath 102800e09d Sat Dec 16 10:33:11 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* Makerules: Use $(do-install-so) for installing shared objects.
	(do-install-so): New canned sequence.  Make a symlink LIB.so after
	installing LIB.so.VERSION.

	* inet/netinet/in.h: Fixed typo in IPPORT_WHOIS.
1995-12-17 10:00:23 +00:00
Roland McGrath 293e360a25 Fixed typo in IPPORT_WHOIS. 1995-12-16 15:32:59 +00:00
Stan Cox d277428889 (AViiON): Add ix86-dg-dgux 1995-12-16 03:32:35 +00:00
Stan Cox 2cb7465b38 (i*86*) Change [345] to [3456] 1995-12-15 15:43:33 +00:00
Roland McGrath 05be689b57 Fri Dec 15 04:41:22 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
* stdio-common/Makefile (tests): Add bug10.
	* stdio-common/bug10.c: New file.  From HJ Lu.

	* stdio-common/tstdiomisc.c: Make more test-suite like: exit
	status tells about successful run.

	* stdio-common/vfscanf.c [!USE_IN_LIBIO]: Use `flags' to check
	format correctness.
	Correct handling of trailing white spaces in format + EOF.

Fri Dec 15 01:31:56 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>

	* stdio-common/Makefile (tests): Add bug8 and bug9.
	* stdio-common/bug8.c, stdio-common/bug9.c: New tests.

	* stdio-common/vfscanf.c: Fix bug in dynamic buffer handling.

	* stdlib/strtod.c: Correct spelling: nominator -> numerator.
	Thanks to Jim Meyering.

Sat Nov 25 06:05:12 1995  H.J. Lu  <hjl@nynexst.com>

	* stdio-common/vfscanf.c: Always check width !=0.
	Correctly handle %%.
1995-12-15 05:22:35 +00:00
Roland McGrath faf92f2a62 Thu Dec 14 02:28:22 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* posix/glob.c (glob_in_dir): Cast result of opendir to __ptr_t,
	and cast STREAM to DIR * before passing to readdir and closedir.

Wed Dec 13 22:06:07 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* hurd/hurdsig.c (_hurd_internal_post_signal: suspend): Reply
	after aborting RPCs but before calling proc_mark_stop.
1995-12-14 10:00:22 +00:00
Roland McGrath 6a7169a509 (_hurd_internal_post_signal: suspend): Reply after aborting RPCs but before calling proc_mark_stop. 1995-12-14 03:05:50 +00:00
Ian 26bd65c364 Accept *-*-ieee*. 1995-12-13 21:43:08 +00:00
Roland McGrath a4e2c88cf4 Regenerated
Mon Dec 11 20:07:54 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* posix/glob.c [! STDC_HEADERS]: Declare getenv.
	(glob): Avoid using function as value.
1995-12-12 04:32:33 +00:00
Roland McGrath 3be01400fd Mon Dec 11 20:07:54 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* posix/glob.c [! STDC_HEADERS]: Declare getenv.
	(glob): Avoid using function as value.

	* elf/rtld.c (dl_main): When mapping argument executable, set
	l_name to "", not l_libname.
	After loading DT_NEEDED library, set its l_type to lt_library.

	* sysdeps/mach/hurd/mmap.c: Don't interpret MAP_INHERIT to mean
	VM_INHERIT.  We can't handle MAP_INHERIT easily.
	Handle non-page-aligned addresses if congruent to offset.

	* elf/dl-init.c: Skip the initializer for l_type lt_executable
	with l_name "". Start at _dl_loaded; don't skip the first element.

	* elf/dl-load.c (MAP_FILE): Define to zero if undefined.
	(MAP_COPY): Define to MAP_PRIVATE if undefined.
	(_dl_map_object_from_fd): Don't use MAP_INHERIT in mmap calls.
	If file it ET_EXEC, set its l_type to lt_executable.
1995-12-12 04:29:09 +00:00
Roland McGrath 65bf5fa317 Regenerated
Fri Dec  8 13:04:51 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* posix/glob.c: Implement new options GLOB_ALTDIRFUNC, GLOB_BRACE,
	GLOB_TILDE, GLOB_NOMAGIC.
	(glob): Use stat instead of lstat to determine directoriness.
	* posix/glob.h (GLOB_ALTDIRFUNC, GLOB_BRACE, GLOB_NOMAGIC, GLOB_TILDE):
	New flag bits.
	(__GLOB_FLAGS): Include them.
	(glob_t): New members gl_closedir, gl_readdir, gl_opendir, gl_lstat,
	gl_stat.
1995-12-12 02:42:14 +00:00
Roland McGrath 9b8a44cd18 (MAP_FILE): Define to zero if undefined. (MAP_COPY): Define to MAP_PRIVATE if undefined. (_dl_map_object_from_fd): Don't use MAP_INHERIT in mmap calls. If file it ET_EXEC, set its l_type to lt_executable. 1995-12-12 01:07:35 +00:00
Per Bothner d72d8b1328 (powerpc-harris-powerunix): Add guess for port to new target. 1995-12-12 00:47:21 +00:00
Roland McGrath 25b86c05c3 Sun Dec 10 09:56:06 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/dl-minimal.c (malloc): Use MAP_PRIVATE in mmap call.
1995-12-11 10:00:21 +00:00
Roland McGrath 787e4db95c Fri Dec 8 13:04:51 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* locale/error.c, locale/error.h: Files removed.
	* locale/Makefile (distribute): Remove error.h.
	(lib-modules): Remove error.

	* hurd/hurdlookup.c (__hurd_file_name_lookup_retry): For "tty"
	magic, return ENXIO if no ctty.

	* sysdeps/mach/hurd/mmap.c: For MAP_FIXED, deallocate a previous
	mapping if vm_map fails for that reason.

	* posix/glob.c: Implement new options GLOB_ALTDIRFUNC, GLOB_BRACE,
	GLOB_TILDE, GLOB_NOMAGIC.
	(glob): Use stat instead of lstat to determine directoriness.
	* posix/glob.h (GLOB_ALTDIRFUNC, GLOB_BRACE, GLOB_NOMAGIC, GLOB_TILDE):
	New flag bits.
	(__GLOB_FLAGS): Include them.
	(glob_t): New members gl_closedir, gl_readdir, gl_opendir, gl_lstat,
	gl_stat.

	* elf/elf.h (ET_NUM, SHT_NUM, STB_NUM, STT_NUM, PT_NUM): New macros.

	* sysdeps/unix/sysv/linux/sys/mman.h: Include <linux/mman.h> to
	define all the bit values.
	(MAP_*, MCL_*): Macros removed.
1995-12-09 10:00:22 +00:00
Roland McGrath c994299d50 Thu Dec 7 02:27:56 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* resolv/res_comp.c, resolv/res_debug.c, resolv/res_send.c:
	Updated from BIND 4.9.3-BETA27.

Wed Dec  6 18:44:01 1995  Miles Bader  <miles@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/select.c (__select): Swap size args to mach_msg.

	* sysdeps/mach/hurd/select.c (__select): Frob TYPES correctly when
	we get a delayed reply.
	Only grab values out of entries in TYPES that have SELECT_RETURNED
 	turned on, and turn it on whenever an rpc returns.
	Only clear bits in the user's fdsets -- those needing to be set
	should be already.
	Use SELECT_ALL in appropiate places.
	(SELECT_RETURNED, SELECT_ALL): New macros.

Wed Dec  6 09:10:39 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* sysdeps/mach/hurd/sys/param.h (NBBY): New macro.

	* gnu-versions.h (_GNU_GLOB_INTERFACE_VERSION): New macro.
1995-12-08 10:00:22 +00:00
Roland McGrath a4219bc4c0 Updated from BIND-4.9.3-BETA27. 1995-12-07 19:37:55 +00:00
Miles Bader 0c7b844d25 (__select): Still clear the user's bits for an fd when SELECT_RETURNED isn't set. Only clear bits in the user's fdsets -- those needing to be set should be already. Use SELECT_ALL in appropiate places. (SELECT_ALL): New macro. 1995-12-07 03:03:31 +00:00
Miles Bader 53525291ae (__select): Swap size args to mach_msg. 1995-12-06 23:45:07 +00:00
Roland McGrath 756245d743 (NBBY): New macro. 1995-12-06 14:13:00 +00:00
Roland McGrath 7353787873 (_GNU_GLOB_INTERFACE_VERSION): New macro. 1995-12-06 14:10:23 +00:00
erich 1ff0303078 Recognize aof in the OS field. 1995-12-06 11:57:46 +00:00
Roland McGrath edbba60a5e Tue Dec 5 14:00:17 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* misc/Makefile (headers): Add error.h, err.h.
	(routines): Add error, err.
	(gpl2lgpl): New variable.
	* misc/err.c: New file.
	* misc/err.h: New file.
	* misc/error.c, misc/error.h: New files.

	* sysdeps/mach/hurd/ioctl.c: Fix typo in last change.

	* Makeconfig (+link): Translate libc% from $^, not just libc.a.
	(link-libc): Append $(libc.so-version) to libc.so.
	(built-program-cmd): Fix comma usage.
	* Makerules [libc.so-version] (libc.so$(libc.so-version)): Make a
	symlink to libc.so in the build directory.
	* Rules ($(others) $(tests)): Depend on the library that appears
	in $(link-libc).
	(%.out): Use $(built-program-cmd) in commands.

	* posix/unistd.h [__USE_MISC]: Declare brk, sbrk.

	* sysdeps/generic/setenv.c: Added canonical portability cruft.
	(setenv): Use realloc on LAST_ENVIRON instead of always copying.
	(unsetenv): New function.
	* stdlib/stdlib.h [__USE_BSD]: Declare unsetenv.
	* sysdeps/generic/putenv.c: Rewritten using setenv and unsetenv.

	* libio/Makefile (routines): Remove iofscanf, add iopopen, pclose.
1995-12-06 10:00:22 +00:00
Paul Eggert 034ff8def9 (transformbasename): Fix misspelling in initialization. 1995-12-06 09:44:53 +00:00
Roland McGrath 196980f511 Updated from ../gpl2lgpl.sed /home/gd/gnu/lib/error.c 1995-12-06 00:14:32 +00:00
Roland McGrath 77a58cad3f Tue Dec 5 02:27:32 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
* libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose.

	* libio/iofscanf.c: Remove file.

	* libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string
        termination.

	* libio/iopopen.c: New file from GNU libio.

	* libio/memstream.c: Fixed bug in fclose handling.  Instead of
	providing a close callback we need a finish callback.

	* libio/pclose.c: New file.  Derived from popen.c in GNU libio.

	* posix/gnu/types.h: Fixed typo.

	* stdio-common/errnobug.c: fputs returns EOF in error case.  Do
	not test for != 0.

	* stdio-common/printf-parse.h (parse_one_spec): Do not force
	padding with ' ' if precision is given.  Fix by HJ Lu.

	* stdio-common/printf_fp.c: Fix comment.

	* stdio-common/tfformat.c, stdio-common/tiformat.c,
	stdio-common/tstdiomisc.c: New files from GNU libio test suite.

	* stdio-common/tstgetln.c: Provide ssize_t type when testing
	libio.

	* stdio-common/vfprintf.c (outchar): Use PUTC instead of putc.
	(vfprintf): Cleasr args_type array before using it.
	When printing 0 as an integer with precision 0 nothing must be
	written for the number.
	Based on patch by HJ Lu.

	* stdio-common/vfscanf.c: Remove fixed input buffer.  Now we
        have a dynamically extended buffer.

	* stdlib/strtod.c: Merge with version in Linux libc.  This fixes
        some bugs with handling of very small numbers and has different
        solution for formaer patches.

	* sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename
        macros r1 and r2 to t1, and t2 resp.  This is necessary because
        glibc headers also define r1.
Tue Dec  5 02:27:32 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>

	* libio/Makefile [routines]: Remove iofscanf, add iopopen, pclose.

	* libio/iofscanf.c: Remove file.

	* libio/iogetdelim.c (_IO_getdelim): Correct stupid bug at string
        termination.

	* libio/iopopen.c: New file from GNU libio.

	* libio/memstream.c: Fixed bug in fclose handling.  Instead of
	providing a close callback we need a finish callback.

	* libio/pclose.c: New file.  Derived from popen.c in GNU libio.

	* posix/gnu/types.h: Fixed typo.

	* stdio-common/errnobug.c: fputs returns EOF in error case.  Do
	not test for != 0.

	* stdio-common/printf-parse.h (parse_one_spec): Do not force
	padding with ' ' if precision is given.  Fix by HJ Lu.

	* stdio-common/printf_fp.c: Fix comment.

	* stdio-common/tfformat.c, stdio-common/tiformat.c,
	stdio-common/tstdiomisc.c: New files from GNU libio test suite.

	* stdio-common/tstgetln.c: Provide ssize_t type when testing
	libio.

	* stdio-common/vfprintf.c (outchar): Use PUTC instead of putc.
	(vfprintf): Cleasr args_type array before using it.
	When printing 0 as an integer with precision 0 nothing must be
	written for the number.
	Based on patch by HJ Lu.

	* stdio-common/vfscanf.c: Remove fixed input buffer.  Now we
        have a dynamically extended buffer.

	* stdlib/strtod.c: Merge with version in Linux libc.  This fixes
        some bugs with handling of very small numbers and has different
        solution for formaer patches.

	* sysdeps/i386/i586/add_n.S, sysdeps/i386/i586/sub_n.S: Rename
        macros r1 and r2 to t1, and t2 resp.  This is necessary because
        glibc headers also define r1.
1995-12-05 03:35:55 +00:00
Roland McGrath b5a08c5aca Mon Dec 4 12:10:28 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* stdlib/gen-mpn-copy (translations): Updated for new layout in
	GMP 1.910.

	* malloc/malloc.c (__malloc_initialize): Renamed from initialize;
	made global.
	(malloc): Caller changed.
	* malloc/realloc.c (realloc): Call __malloc_initialize if
	necessary, before checking hook.
	* malloc/malloc.h: Declare __malloc_initialize.

	* sysdeps/mach/hurd/ioctl.c: For IOC_VOID request, send ARG itself
	as integer_t arg in RPC.
1995-12-04 19:00:50 +00:00
Roland McGrath ba848785bb Updated from ../=mpn/gmp-1.910 1995-12-04 18:37:56 +00:00
Linda A. Walsh c13a4f3dbd * config.guess: Recognize HP model 816 machines as having a PA1.1 processor. 1995-12-04 18:22:22 +00:00
Roland McGrath 99cf7e3eba For IOC_VOID request, send ARG itself as integer_t arg in RPC. 1995-12-04 17:10:03 +00:00
Roland McGrath 683158e0c4 * sysdeps/mach/hurd/brk.c (DATA_SIZE): Bump to 128MB.
(_hurd_set_brk): Try to allocate more space when we run out.
	* sysdeps/generic/sbrk.c: If __curbrk is zero, call __brk with
	zero and examine it again.
	* sysdeps/unix/sysv/linux/i386/brk.c: New file.
	* sysdeps/unix/sysv/linux/i386/brk.S: File removed.
	* sysdeps/unix/sysv/linux/i386/sbrk.S: File removed.
	* sysdeps/unix/sysv/linux/dl-sysdep.c: New file.
1995-12-03 10:00:22 +00:00
Roland McGrath 0fe4e55291 Sat Dec 2 03:47:27 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/i386/sbrk.S: File removed.

	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start) [DL_SYSDEP_INIT]:
	Invoke this macro before calling DL_MAIN.

	* malloc/malloc.c (malloc): Do initialization here, before
	checking the hook.
	(_malloc_internal): Don't do it here.
1995-12-02 10:00:20 +00:00
Roland McGrath 376fd36e2d (_dl_sysdep_start) [DL_SYSDEP_INIT]: Invoke this macro before calling DL_MAIN. 1995-12-02 09:03:14 +00:00
Per Bothner 8e2e98a2a9 * config.guess: Recognize Pentium under SCO. 1995-11-30 21:59:48 +00:00
Roland McGrath b2518f55c0 Wed Nov 29 12:30:50 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* libio/vsnprintf.c (__vsnprintf): Define as alias.
	* libio/iovsscanf.c (__vsscanf): Define as alias.
	* asprintf.c: Remove libio adaptation code added by drepper.
	* dprintf.c: Likewise.
	* printf.c: Likewise.
	* scanf.c: Likewise.
	* snprintf.c: Likewise.
	* sprintf.c: Likewise.
	* sscanf.c: Likewise.
	* vprintf.c: Likewise.
	* stdio-common/vfscanf.c [USE_IN_LIBIO] (__vfscanf): New wrapper
	function.
	(vfscanf): Define unconditionally.

	* sysdeps/i386/dl-machine.h (elf_machine_rel): If SYM is null, use
	zero for value.

	* misc/getpass.c: Write a newline after reading the unechoed
	password.
1995-11-30 04:49:04 +00:00
Roland McGrath b7843ea9ff Mon Nov 27 19:24:18 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* posix/Makefile (routines): Add getsid.
	* sysdeps/unix/sysv/linux/getsid.S: New file.
	* sysdeps/mach/hurd/getsid.c: New file.
	* sysdeps/stub/getsid.c: New file.
	* posix/unistd.h [__USE_GNU]: Declare getsid.
1995-11-28 10:00:22 +00:00
Roland McGrath 1ed0083ca9 * sysdeps/unix/sysv/linux/sys/mman.h: Add prototypes for new functions 1995-11-27 10:00:22 +00:00
Roland McGrath f45e34fcae Sun Nov 26 12:44:38 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* libc-symbols.h (N_): New macro.
1995-11-26 17:45:08 +00:00
Roland McGrath cbd3dceb39 Sat Nov 25 02:48:47 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
* assert/assert-perr.c, assert/assert.c, inet/rcmd.c,
	malloc/mcheck.c, malloc/vm-limit.c, posix/getconf.c, posix/id.c,
	resolv/herror.c, sunrpc/auth_unix.c, sunrpc/clnt_perr.c,
	sunrpc/clnt_raw.c, sunrpc/get_myaddr.c, sunrpc/pmap_clnt.c,
	sunrpc/pmap_rmt.c, sunrpc/portmap.c, sunrpc/rpc_main.c,
	sunrpc/rpc_parse.c, sunrpc/rpc_scan.c, sunrpc/rpc_util.c,
	sunrpc/rpcinfo.c, sunrpc/svc_simple.c, sunrpc/svc_tcp.c,
	sunrpc/svc_udp.c, time/zdump.c, time/zic.c: Mark translatable
	strings.
Sat Nov 25 02:48:47 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>

	* assert/assert-perr.c, assert/assert.c, inet/rcmd.c,
	malloc/mcheck.c, malloc/vm-limit.c, posix/getconf.c, posix/id.c,
	resolv/herror.c, sunrpc/auth_unix.c, sunrpc/clnt_perr.c,
	sunrpc/clnt_raw.c, sunrpc/get_myaddr.c, sunrpc/pmap_clnt.c,
	sunrpc/pmap_rmt.c, sunrpc/portmap.c, sunrpc/rpc_main.c,
	sunrpc/rpc_parse.c, sunrpc/rpc_scan.c, sunrpc/rpc_util.c,
	sunrpc/rpcinfo.c, sunrpc/svc_simple.c, sunrpc/svc_tcp.c,
	sunrpc/svc_udp.c, time/zdump.c, time/zic.c: Mark translatable
	strings.
1995-11-26 17:37:11 +00:00
Roland McGrath fbaad1494f Sun Nov 26 02:00:02 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
* misc/syslog.c (vsyslog) [USE_IN_LIBIO]: Adapted for libio.

Thu Nov 23 02:21:55 1995  Ulrich Drepper  <drepper@gnu.ai.mit.edu>

	* sysdeps/unix/sysv/linux/{mlock,munlock,mlockall,munlockall}.S:
	New files.
	* sysdeps/unix/sysv/linux/mman.h: Add prototypes for new functions
	mlock, munlock, mlockall, and munlockall.
1995-11-26 17:32:10 +00:00
Roland McGrath f44820454c Thu Nov 23 18:26:52 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* configure.in (--enable-libio): Set $stdio based on $enableval,
	not always to libio.

Thu Nov 23 18:06:48 1995  Richard Stallman  <rms@gnu.ai.mit.edu>

	* malloc/malloc.c (_malloc_internal): Can't use
	get_contiguous_space when the heap info table
	will be growing.  Account for new contiguous space in _heaplimit.
1995-11-24 10:00:21 +00:00
Roland McGrath 42d2676e7c Wed Nov 22 12:37:39 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/i386/sysdep.S (_errno): Define as alias
	for errno.

	* stdio-common/vfprintf.c [USE_IN_LIBIO] (vfprintf): Define as
	alias for _IO_vfprintf.

	* sysdeps/unix/sysv/linux/sockaddrcom.h: File removed.

	* sysdeps/unix/sysv/linux/i386/init-first.c (init): Use
	__fpu_control instead of ___fpu_control.
	* sysdeps/unix/sysv/linux/i386/ieee_fpu.c
	(___fpu_control): Renamed to __fpu_control.
	* sysdeps/unix/sysv/linux/i386/fpu_control.h: Likewise.
	* sysdeps/unix/sysv/linux/i386/fpu_control.c: Likewise.

	* elf/dl-minimal.c: New file.
	* elf/Makefile (rtld-routines): Add dl-minimal.
	* elf/rtld.c (__dgettext, __assert_fail, __assert_perror_fail):
	Functions moved to dl-minimal.c.
	* sysdeps/mach/hurd/dl-sysdep.c (malloc, free, realloc,
	sigjmp_save, longjmp): Likewise.

	* sysdeps/unix/sysv/linux/i386/brk.S (__curbrk): Always initialize
	to &_end, regardless of PIC.

	* stdio-common/vfscanf.c (__vfscanf): Fix arg name in defn.
1995-11-23 04:53:06 +00:00
Roland McGrath 1a3a58fd76 Tue Nov 21 14:12:13 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* malloc/malloc.c (align): Don't check contiguity and call abort.

	* hurd/hurdsig.c (post_reply): Function removed.
	(abort_thread, abort_all_rpcs, _hurdsig_abort_rpcs): Don't call it.
	Take single callback fn arg instead of reply port and type.
	(_hurd_internal_post_signal): Callers changed.
	Cache reply stub fn ptr in local var before UNTRACED might be changed.

	* sysdeps/mach/hurd/mmap.c: Cope with a null write memobj for
	PROT_READ|PROT_WRITE copy mapping.  Pass a proper vm_inherit_t to
	vm_map.

	* elf/rtld.c (_dl_start): For --list, do output and exit before
	relocating.
1995-11-22 10:00:23 +00:00
Roland McGrath 91c7b85dc8 Mon Nov 20 16:19:15 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* intl/Makefile [gettext-srcdir]: Rewrote copying rules to only
	get .c and .h files.

	* malloc/malloc.c (align): Use abort instead of assert.
1995-11-21 10:01:17 +00:00
Roland McGrath 054cc4cc38 Sun Nov 19 18:23:07 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* Makeconfig (+includes): Add $($(stdio)-include).
	(libio-include): New variable.

	* stdlib/strtod.c: Put weak_symbol after function defn.
	* stdlib/strtol.c: Likewise.

	* configure.in (--enable-libio): If not present, set $stdio to
	"default".  Move stdio/libio check to end, so sysdeps fragments
	can affect it.  Reset $stdio to "stdio" if it's "default".
	* sysdeps/unix/sysv/linux/configure: New file.
1995-11-20 10:01:12 +00:00
Roland McGrath 96aa2d94a2 Sat Nov 18 16:46:01 1995 Ulrich Drepper <drepper@gnu.ai.mit.edu>
* libio/Makefile, libio/cleanup.c, libio/clearerr.c, libio/feof.c,
	libio/ferror.c, libio/fgetc.c, libio/filedoalloc.c, libio/fileno.c,
	libio/fileops.c, libio/fputc.c, libio/freopen.c, libio/fseek.c,
	libio/genops.c, libio/getc.c, libio/getchar.c, libio/iofclose.c,
	libio/iofdopen.c, libio/iofflush.c, libio/iofgetpos.c, libio/iofgets.c,
	libio/iofopen.c, libio/iofprintf.c, libio/iofputs.c, libio/iofread.c,
	libio/iofscanf.c, libio/iofsetpos.c, libio/ioftell.c, libio/iofwrite.c,
	libio/iogetdelim.c, libio/iogetline.c, libio/iogets.c, libio/iolibio.h,
	libio/iopadn.c, libio/ioprims.c, libio/ioputs.c, libio/ioseekoff.c,
	libio/ioseekpos.c, libio/iosetbuffer.c, libio/iosetvbuf.c,
	libio/iosprintf.c, libio/ioungetc.c, libio/iovsprintf.c,
	libio/iovsscanf.c, libio/libio.h, libio/libioP.h, libio/putc.c,
	libio/putchar.c, libio/rewind.c, libio/setbuf.c, libio/setlinebuf.c,
	libio/stdfiles.c, libio/stdio.c, libio/stdio.h, libio/strfile.h,
	libio/strops.c, libio/vasprintf.c, libio/vscanf.c, libio/vsnprintf.c:
	New files.  Slightly modified version from Linux libc.

	* libio/memstream.c, libio/vdprintf.c: New files for functions not
	(yet) part of GNU libio.

	* libio/iofopncook.c: Implementation of `fopencookie', mainly written
	by Per Bothner.

	* stdio-common/getline.c: Adapted to libio.
	* stdio-common/snprintf.c: Adapted to libio.
	* stdio-common/vfprintf.c: Adapted to libio.
	* stdio-common/vfscanf.c: Adapted to libio.
	* sysdeps/posix/tempname.c: Adapted to libio.
1995-11-20 03:48:11 +00:00
Roland McGrath a5a81fecc7 Fri Nov 17 17:57:00 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/generic/Makefile (make_siglist): Add missing backslash.

	* sysdeps/generic/dl-sysdep.c (_dl_sysdep_start_cleanup): New
	function.

	* hurd/hurdfault.c: Replace __libc_fatal calls with assert_perror.
	(_hurdsig_fault_init): Remove #if 0 from setting exception port.
	Insert send right for SIGEXC before thread_set_special_port.
	* hurd/hurdsig.c: Replace __libc_fatal calls with assert_perror.
	(_hurdsig_init): Remove #if 0 from setting exception port.

	* sysdeps/mach/hurd/ptrace.c (ptrace: PTRACE_CONT): Use
	HURD_MSGPORT_RPC macro.
1995-11-18 10:00:22 +00:00
Roland McGrath 4cb202902d Thu Nov 16 06:07:49 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/dl-sysdep.c (_dl_sysdep_start_cleanup): New
	function.
	(_dl_sysdep_start): Move cleanup code there.

	* Makeconfig (default-rpath): New variable.
	(link-libc): Use it.
	* elf/Makefile (ld.so): Pass -rpath=$(default-rpath).
	* elf/rtld.c (_dl_rpath): New variable.
	(_dl_start): Set it from rtld_map's DT_RPATH.
	Call _dl_setup_hash on rtld_map.
	(dl_main): Cache address of _exit in variable before relocating,
	and use that in later calls.  Call _dl_sysdep_start_cleanup before
	relocating.  Keep track of dependency order while loading; remove
	rtld_map from chain, and reinsert in proper order if there is a
	dependency on it.

	* sysdeps/generic/Makefile (make_siglist): Pass
	-DSIGNUM_H=... with config's signum.h location.
	* sysdeps/generic/make_siglist.c: Include SIGNUM_H to define
	signal numbers.
	(HAVE_STRSIGNAL, HAVE_PSIGNAL): Define these before including signame.c
	(main): Deansideclize output.

	* elf/dl-load.c (_dl_map_object): Use _dl_rpath variable in place
	of DEFAULT_RPATH macro.
	* elf/Makefile: Undo last change.

	* sysdeps/mach/hurd/dl-sysdep.c (free): Don't abort, just nop.
1995-11-17 02:33:47 +00:00
Roland McGrath 8738e7f8b0 * elf/dl-lookup.c (_dl_lookup_symbol): Undefined symbol is no
error if weak.

	* elf/Makefile (default-rpath): New variable.
	(CPPFLAGS): Append -DDEFAULT_RPATH=....
	* elf/dl-load.c (_dl_map_object): Use DEFAULT_RPATH instead of
	hard-coded "/lib:/usr/lib".
1995-11-16 02:37:06 +00:00
Roland McGrath ec967c06ac Wed Nov 15 19:22:07 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/dl-sysdep.c: Include _itoa.h from stdio-common
	instead of stdio.
	(_dl_sysdep_start): If passed user entry is zero and
	EXEC_STACK_ARGS flag set, reset user entry to &_start.

	* elf/rtld.c (dl_main): Only call _dl_setup_hash if there is a
	DT_HASH element.

	* libc-symbols.h [HAVE_ELF] (symbol_set_declare): Gratuitously
	repeat weak decl using weak_symbol macro, in case using broken GCC
	(<2.8).

Wed Nov 15 18:49:55 1995  Ulrich Drepper  <drepper@ipd.info.uni-karlsruhe.de>

	* sysdeps/i386/isnanl.c: New file.
	* sysdeps/i386/isinfl.c: New file.
1995-11-16 00:44:18 +00:00
Roland McGrath 2ede96c936 Tue Nov 14 18:44:21 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* malloc/free.c (free): Moved null and aligned_blocks checks
	inside _free_internal.
1995-11-15 00:27:30 +00:00
Roland McGrath 9199ec6eb2 Mon Nov 13 15:23:01 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* malloc/malloc.c (morecore): Fix inverted test in allocating new
	info table.

	* malloc/malloc.c (align): Fix assertion.

	* malloc/malloc.c: Include assert.h.

	* libc-symbols.h: Use __attribute__ for GCC 2.8, not 2.7.

	* malloc/malloc.h [emacs] (emacs_loser_valloc): Macro removed.
	(valloc): Protect decl with [! (_MALLOC_INTERNAL && emacs)].
1995-11-14 10:00:21 +00:00
Roland McGrath accc07a981 * malloc/malloc.c (align): Assert that space for alignment
adjustment is same original space.

	* hurd/hurdprio.c (_hurd_priority_which_map): Cast vm_deallocate
	arg to vm_address_t.
1995-11-11 10:01:11 +00:00
Roland McGrath 75914335da Fri Nov 10 14:15:21 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* hurd/hurdsig.c (_hurd_internal_post_signal): For SIGNO == 0,
	skip straight to pending check.  When UNTRACED, resume process
	from suspension first.

	* intl/Makefile (headers): New variable, libintl.h.
	[gettext-srcdir]: New rules to copy source from $(gettext-srcdir)/intl.
	* configure.in: Check for --with-gettext arg.

Fri Nov 10 13:51:30 1995  Richard Stallman  <rms@gnu.ai.mit.edu>

	* malloc/malloc.c (get_contiguous_space): New function.
	(morecore): Rewrite allocating new malloc info table.
	(_malloc_internal): Use get_contiguous_space.

Fri Nov 10 13:03:40 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* hurd/hurdexec.c (_hurd_exec): If exec'ing self, pass
	_hurd_msgport to be destroyed.

	* Makerules (installed-libcs): Filter out %_pic.a.

	* hurd/hurdinit.c (_hurd_proc_init): When traced, use msg_sig_post
	to our msgport to take SIGTRAP, instead of _hurd_raise_signal.

	* hurd/Makefile (user-interfaces): Add hurd/process_request.
1995-11-10 20:38:31 +00:00
Roland McGrath d7435cd836 Wed Nov 8 16:31:25 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* termios/Makefile (headers): Add sys/ttychars.h.
	* termios/sys/ttychars.h: New file, incorporated from 4.4BSD-Lite
	for compatibility.

	* signal/signal.h [__USE_BSD] (sig_t): New typedef.

Wed Nov  8 15:12:47 1995  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>

	* sysdeps/mach/hurd/ptrace.c (ptrace) [PTRACE_TRACEME]: Notify the
	proc server that we are now traced.
1995-11-09 10:00:21 +00:00
Roland McGrath 7606603541 [__USE_BSD] (sig_t): New typedef. 1995-11-08 21:31:12 +00:00
Thomas Bushnell, BSG f535a036af (ptrace) [PTRACE_TRACEME]: Notify the proc server that we are now traced. 1995-11-08 20:12:30 +00:00
Roland McGrath 094bacdbd8 * elf/Makefile (ldd): Make it executable.
* Makeconfig (config-LDFLAGS): Find dynamic linker in $(slibdir).

	* Makeconfig (slibdir): New variable.
	* Makerules (install): Install libc.so in $(slibdir).
	* elf/Makefile (install-others): Install ld.so and ld-linux.so.1
	in $(slibdir).
1995-11-08 02:28:15 +00:00
Roland McGrath 86d2c878ac Tue Nov 7 12:29:46 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/linux-compat.c: New file.
	* elf/Makefile (distribute): Add linux-compat.c.
	(generated): Add librtld.so.
	[$(config-os)=linux*] (extra-objs): Add linux-compat.so.
	[$(config-os)=linux*] (extra-objs): Add ld-linux.so.1.
	(librtld.so): New target.
	(ld.so, ld-linux.so.1): Make from librtld.so.

	* elf/rtld.c (dl_main): Instead of weak call to _dl_compat_init,
	call our own DT_INIT if we have one (and then clear it).
	(__dgettext): New weak function.

	* intl/localealias.c (read_alias_file): Avoid sprintf; use memcpy
	by hand instead.

	* sysdeps/generic/_strerror.c (_strerror_internal): Use _itoa
	instead of snprintf.

	* sysdeps/mach/_strerror.c (_strerror_internal): Don't write
	BUF[BUFLEN].

	* elf/rtld.c (rtld_map): New static variable.
	(_dl_start): Use a differently named local BOOTSTRAP_MAP for the
	bootstrapping.  Then copy data into `rtld_map'.
	(dl_main): Finish filling in rtld_map and link it into the chain,
	instead of allocating a new structure.
	(dl_main): Call _dl_compat_init if it is defined (use weak ref).

	* elf/dlsym.c: Fix last change: move REF out of `doit'.


	control.
	using it.

	and cwdir ports.
	functions.
	these.
	$(libdir)(rtld-installed-name).

	leading zeroes.

	in the rhs.
	pattern rule.


	never know.
	(fork): Use symbol_set_* macros for _hurd_fork_locks.
	* sysdeps/unix/sysv/sysv4/linux/i386/sysdep.S (__syscall_error):
 	instead of unix/sysv.

	-dynamic-linker.

	(__printf_fp): Last arg ARGS is now `const void **const';

	locale/C-ctype.c.
	* sysdeps/mach/hurd/sigsuspend.c: Likewise.
	* sysdeps/mach/hurd/mips/sigreturn.c: Likewise.
	alias gethostname.
	setitmr
	setpgrp
	(_S_msg_get_exec_flags, _S_msg_set_exec_flags,
	(abort_thread, abort_rpcs): Take same new arg and pass it through.
1995-11-07 21:46:52 +00:00
Roland McGrath 51093422b2 Mon Nov 6 16:20:14 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* elf/dlsym.c: Return the proper value, not just the defining
	object's loadbase.
1995-11-07 10:00:21 +00:00
Roland McGrath f797c38303 * stdio-common/vfprintf.c (%c): Count the character itself towards
the field width in all cases.
1995-11-06 10:00:20 +00:00
Roland McGrath e380bf6248 Sun Nov 5 16:09:13 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/getpriority.c (getpriority): Cast
	__vm_deallocate arg to vm_address_t.
1995-11-05 21:13:25 +00:00
Roland McGrath 853f0eead1 Fri Nov 3 17:27:49 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/sendto.c: Don't pass BINDING arg to
	socket_create_address.
	* sysdeps/mach/hurd/connect.c: Likewise.
	* sysdeps/mach/hurd/bind.c: Likewise.

	* hurd/hurdprio.c (_hurd_priority_which_map): Pass threadwaits
	args to proc_getprocinfo.
	* sysdeps/mach/hurd/getpriority.c: Likewise.

	* hurd/hurdmsg.c (_S_msg_report_wait): New stub function.
1995-11-03 22:42:06 +00:00
Roland McGrath 27cc33c3b4 Thu Nov 2 19:24:37 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/i386/sysdep.S (errno): Define as common.
1995-11-03 10:00:20 +00:00
Roland McGrath 80b55d320b * sysdeps/mach/hurd/getpriority.c (getpriority): Pass
PI_FETCH_TASKINFO to proc_getprocinfo and through
	_hurd_priority_which_map.

	* sysdeps/mach/hurd/setpriority.c (setpriority): Pass new arg to
	_hurd_priority_which_map.
	* hurd/hurdprio.c (_hurd_priority_which_map): New arg PI_FLAGS,
	passed through to proc_getprocinfo RPC.
	* hurd/hurd/resource.h: Add PI_FLAGS arg in decl.
1995-11-01 10:00:20 +00:00
Roland McGrath 3bbceb1287 Tue Oct 31 00:07:29 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/mach/hurd/group_member.c: New file.
	* sysdeps/generic/group_member.c: New file.

	* Makerules (lib-noranlib): Don't depend on $(install-lib).
	(others): Do.
	* extra-lib.mk: Fix test of $(lib)-no-lib-dep.

Mon Oct 30 12:33:10 1995  Roland McGrath  <roland@churchy.gnu.ai.mit.edu>

	* Rules (others): Depend on $(extra-objs).

	* posix/unistd.h [__USE_GNU]: Declare group_member, __group_member.
	* posix/Makefile (routines): Add group_member.

	* sysdeps/posix/euidaccess.c: New file, adapted from fileutils.

	* sysdeps/unix/sysv/linux/i386/sigaction.c: Tighten constraint for
	SIG operand in asm so it must be a register.
	Add dead return to quiet gcc warning.

	* Makerules (sysd-rules): Write a defn for sysd-rules-done.
	[! sysd-rules-done]: Inhibit deps.
1995-10-31 06:54:40 +00:00
Roland McGrath 3e2ee7271d Thu Oct 26 23:11:11 1995 Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
* sysdeps/unix/sysv/linux/poll.c: Don't define as stub.  Use
	simulation of system call using select.

	* sysdeps/unix/sysv/linux/signal.c: Use POSIX implementation.

	* sysdeps/unix/sysv/linux/statbuf.h: Define _STAT_VER.

	* sysdeps/unix/sysv/linux/i386/sigaction.c: Correct parameter
	name usage (new->act, old->oact).
	Correct asm statement because of gcc strangeness.
	
	* sysdeps/i386/i586/strchr.S: Correct typos: cmp -> cmpb.

	* sunrpc/clnt_perr.c: Remove declaration of sys_errlist.  They
	conflict with the ones in stdio.h.

	* string/tester.c: %Z is no complete format.  Change to %Zd.

	* sysdeps/mach/hurd/symlink.c (__symlink): Ditto.
1995-10-30 16:40:52 +00:00
Roland McGrath f094496c12 Thu Oct 26 18:13:33 1995 Miles Bader <miles@gnu.ai.mit.edu>
* sysdeps/mach/hurd/bind.c (bind): Swap args to dir_link.
	* sysdeps/mach/hurd/link.c (__link): Ditto.
	* sysdeps/mach/hurd/mknod.c (__mknod): Ditto.
	Include "stdio-common/_itoa.h" instead of "stdio/_itoa.h".

	* sysdeps/mach/hurd/symlink.c (__symlink): Ditto.
1995-10-27 09:00:21 +00:00
Miles Bader bf899faa49 Include "stdio-common/_itoa.h" instead of "stdio/_itoa.h". 1995-10-26 23:11:02 +00:00
Miles Bader 29370ca488 Swap args to dir_link. 1995-10-26 22:19:57 +00:00
Roland McGrath efc755b282 Thu Oct 26 00:11:13 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/i386/sigaction.c: New file.

	* sysdeps/unix/sysv/linux/i386/xstat.S: Don't use JUMPTARGET macro
	on syscall_error.  For PIC, it is a local label;
	for non-PIC, JUMPTARGET expands to the unadorned name anyway.
	* sysdeps/unix/sysv/linux/i386/xmknod.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/syscall.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/socket.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/sbrk.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/mmap.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/brk.S: Likewise.
1995-10-26 04:17:49 +00:00
Roland McGrath 4133498776 Thu Oct 26 03:01:22 1995 Ulrich Drepper <drepper@ipd.info.uni-karlsruhe.de>
* sysdeps/unix/sysv/linux/syscall.h: Strip list of syscalls in
	comment to the necessary ones.  Add _readv and _writev.

	* sysdeps/unix/configure.in: Change syntax for system call test
	candidates and adapt sed script for this.  Now use : to separate
	syscall name and file name.

	* sysdeps/unix/sysv/linux/i386/sysdep.h (ENTRY): System call
	number is now set is DO_CALL.  So call with additional argument.
	(DO_CALL): Takes an additional argument.  Load system call
	number according to new argument.
	(SYSCALL_ERROR_HANDLER): Add ; after last ret statement.
	* sysdeps/unix/sysv/linux/i386/brk.S [PIC]: Define __syscall_error
	locally using SYSCALL_ERROR_HANDLER macro.
	* sysdeps/unix/sysv/linux/i386/mmap.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/sbrk.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/socket.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/xmknod.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/xstat.S: Likewise.
	* sysdeps/unix/sysv/linux/i386/syscall.S: Likewise.
	Don't use DO_CALL macro; instead use lower level macros for better
	control. 

	* sysdeps/unix/sysv/linux/sigaction.h: New file.
	* sysdeps/unix/sysv/linux/sigaction.S: File removed.
	* sysdeps/unix/sysv/linux/signal.S: File removed.
1995-10-26 04:01:17 +00:00
Roland McGrath c14e4c326d * hurd/hurdstartup.c (_hurd_startup): Use new
exec_startup_get_info RPC from exec_startup.defs
	in place of old exec_startup from exec.defs.  Remove kludge to
	guess user entry and phdr locations, since the new RPC gives us
	that info.

	* sysdeps/generic/_strerror.c: Undo last change.
1995-10-26 03:59:27 +00:00
Roland McGrath f44f9c33df * stdio/stdio.h (sys_errlist, _sys_errlist): Declare const. 1995-10-26 03:38:19 +00:00
Roland McGrath ff9bef7f88 Wed Oct 25 14:23:35 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/stat.c: New file.
	* sysdeps/unix/sysv/linux/fstat.c: New file.
	* sysdeps/unix/sysv/linux/lstat.c: New file.
	* sysdeps/unix/sysv/linux/i386/stat.S: File removed.
	* sysdeps/unix/sysv/linux/i386/fstat.S: File removed.
	* sysdeps/unix/sysv/linux/i386/lstat.S: File removed.
1995-10-25 19:20:45 +00:00
Roland McGrath 03a7582576 * sysdeps/unix/sysv/linux/i386/sysdep.h (SYSCALL_ERROR_HANDLER):
New macro.
	(PSEUDO): Use it instead of SYSCALL_PIC_SETUP and jmp syscall_error.

	* sysdeps/unix/sysv/linux/i386/sysdep.S (__syscall_error): Define
	only #ifndef PIC.

	* Makeconfig (built-program-cmd): New variable.
	* sunrpc/Makefile (rpcgen-cmd): Use $(built-program-cmd).
	* time/Makefile (zic-cmd): Likewise.

	* hurd/Makefile (user-interfaces): Add hurd/exec_startup.
1995-10-25 02:19:39 +00:00
Roland McGrath e97ec51d01 * sunrpc/Makefile (librpcsvc-no-lib-dep): New variable.
* extra-lib.mk: If $(lib)-no-lib-dep is defined and MAKELEVEL>0,
	make `others' rather than `lib-noranlib' depend on the libraries.
1995-10-24 21:45:10 +00:00
Roland McGrath 21ee716616 Tue Oct 24 15:22:58 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* sysdeps/unix/configure.in: Check for fchdir syscall.
	Improve sed script to allow / on rhs without / on lhs.

Thu Oct 19 03:47:32 1995  Ulrich Drepper  <drepper@ipd.info.uni-karlsruhe.de>

	* sysdeps/unix/sysv/linux/termbits.h: Don't define speed constants.

	* elf/rtld.c: Include _itoa.h from stdio-common instead of stdio.

	* sysdeps/unix/sysv/linux/select.S: New file.
1995-10-24 20:29:05 +00:00
Roland McGrath 1d234146c0 * sysdeps/unix/sysv/linux/i386/sysdep.h (PSEUDO): Use
SYSCALL_PIC_SETUP before jumping to syscall_error.
	* sysdeps/unix/i386/sysdep.h (SYSCALL_PIC_SETUP): New macro.
	(PSEUDO): Use it before jumping to syscall_error.
	* sysdeps/unix/i386/sysdep.S [! PIC]: Don't find GOT address;
	expect it in %ebx on entry.  Pop old %ebx value off stack after
	using it.
1995-10-19 02:20:22 +00:00
Roland McGrath 580c1888be * signal/signal.h [__USE_BSD] (_sys_siglist, sys_siglist): Declare
them.
1995-10-18 19:46:18 +00:00
1069 changed files with 63335 additions and 10216 deletions
+2309 -29
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -170,8 +170,8 @@ mv -f $@.new $@
test ! -d CVS || cvs commit -m'Regenerated: autoconf $(ACFLAGS) $<' $@
endef
configure: configure.in; $(autoconf-it)
%/configure: %/configure.in; $(autoconf-it)
configure: configure.in aclocal.m4; $(autoconf-it)
%/configure: %/configure.in aclocal.m4; $(autoconf-it)
.PHONY: dist
dist: $(tardir).tar.gz $(tardir)-crypt.tar.gz
+56 -16
View File
@@ -1,6 +1,6 @@
# Make the TAGS files.
# Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1992, 1994, 1995, 1996 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
@@ -49,16 +49,12 @@ endif
# Find all sysdep dirs there are, but putting the ones
# we are configured to use first and preserving their order.
all-dirs := $(objdir) \
all-dirs := $(subdir-dirs) \
$(objdir) \
$(sysdep-dirs) \
$(source_dirs) \
$(filter-out $(sysdep-dirs),$(sysdep_dirs))
vpath %.h $(all-dirs)
vpath %.c $(all-dirs)
vpath %.S $(all-dirs)
vpath %.s $(all-dirs)
# Find all the subdirs there are, but putting the ones
# we are configured to use first and preserving their order.
ifndef subdir
@@ -83,15 +79,17 @@ all-dist := $(filter-out %.h %.c %.s %.S,$(all-dist))
# All different versions of $(sources), preserving the configured sysdep
# directory order.
all-sources = $(shell find $(all-dirs) -maxdepth 1 \( -name fnord \
$(foreach file,$(sort $(sources) $(sources:.c=.S) \
$(sources:.c=.s)),\
-o -name $(file)) \
\) -print)
all-sources = $(wildcard $(sort $(sources) $(sources:.c=.S) \
$(sources:.c=.s))) \
$(foreach dir,$(all-dirs),\
$(wildcard \
$(addprefix $(dir)/,\
$(sort $(sources) $(sources:.c=.S) \
$(sources:.c=.s)))))
all-headers = $(shell find $(all-dirs) -maxdepth 1 \( -name fnord \
$(foreach file,$(headers),-o -name $(file)) \
\) -print)
all-headers = $(wildcard $(headers)) \
$(foreach dir,$(all-dirs),\
$(wildcard $(addprefix $(dir)/,$(headers))))
tags_sources := $(strip $(tags_sources))
@@ -100,7 +98,7 @@ ifdef subdir
ifdef tags_sources
$(ETAGS) -o $@ $^
else
# No sources. Create a dummy file.
# No sources. Create a dummy file.
touch $@
endif # tags_sources
else # parent
@@ -116,3 +114,45 @@ $(subdirs:%=%/TAGS):
$(MAKE) -C $(@D) no_deps=t $(@F)
endif # subdir
ifndef XGETTEXT
XGETTEXT = xgettext
endif
ifndef MSGJOIN
MSGJOIN = msgjoin
endif
P = $(..)po
ifdef subdir
domain = $(subdir)
else
domain = libc-top
endif
define extract
@rm -f $@.new
$(XGETTEXT) --keyword=_ --keyword=N_ --sort-output -d - \
> $@.new /dev/null $^
mv -f $@.new $@
endef
$P/$(domain).pot: $(tags_sources); $(extract)
$P/siglist.pot: $(..)sysdeps/generic/signame.c; $(extract)
$P/errlist.pot: $(..)sysdeps/mach/hurd/errlist.c; $(extract)
all-pot = $P/libc-top.pot $(subdirs:%=$P/%.pot) \
$P/siglist.pot $P/errlist.pot
ifndef subdir
$P/SYS_libc.pot: $(all-pot)
@rm -f $@.new
$(MSGJOIN) $^ > $@.new
mv -f $@.new $@
test ! -d CVS || cvs ci -m'Regenerated from source files' $@
$(subdirs:%=$P/%.pot): $P/%.pot: FORCE
$(MAKE) -C $* no_deps=t ../$@
FORCE:
endif
+45 -11
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -56,7 +56,7 @@ objdir = $(ARCH)
endif
endif
# $(common-objdir) is the place to put objects and
# $(common-objdir) is the place to put objects and
# such that are not specific to a single subdir.
ifdef objdir
objpfx = $(objdir)/
@@ -83,7 +83,7 @@ include $(common-objpfx)config.make
# changes and so config.status would be run every time; the dependence of
# config.make should suffice to force regeneration and re-exec, and the new
# image will notice if config.h changed.
$(common-objpfx)config.make: $(common-objpfx)config.status
$(common-objpfx)config.make: $(common-objpfx)config.status $(..)config.h.in
cd $(<D); $(SHELL) $(<F)
# Force the user to configure before making.
@@ -135,6 +135,11 @@ ifndef libdir
libdir = $(exec_prefix)/lib
endif
# Where to install the shared library and dynamic linker.
ifndef slibdir
slibdir = $(exec_prefix)/lib
endif
# Prefix to put on files installed in $(libdir). For libraries `libNAME.a',
# the prefix is spliced between `lib' and the name, so the linker switch
# `-l$(libprefix)NAME' finds the library; for other files the prefix is
@@ -276,18 +281,25 @@ ifndef +link
+link = $(CC) -nostdlib -nostartfiles -o $@ \
$(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) \
$(addprefix $(csu-objpfx),start.o $(+preinit)) \
$(^:$(common-objpfx)libc.a=$(link-libc)) \
$(filter-out $(common-objpfx)libc%,$^) $(link-libc) \
$(addprefix $(csu-objpfx),$(+postinit))
endif
ifndef config-LDFLAGS
ifeq (yes,$(build-shared))
config-LDFLAGS = -Wl,-dynamic-linker=$(libdir)/$(rtld-installed-name)
config-LDFLAGS = -Wl,-dynamic-linker=$(slibdir)/$(rtld-installed-name)
endif
endif
ifndef link-libc
ifeq (yes,$(build-shared))
link-libc = -Wl,-rpath-link=$(common-objdir) -Wl,-rpath=$(libdir) \
$(common-objpfx)libc.so $(gnulib)
link-libc = -Wl,-rpath-link=$(common-objdir) \
$(common-objpfx)libc.so$(libc.so-version) $(gnulib)
# Choose the default search path for the dynamic linker based on
# where we will install libraries.
ifneq ($(libdir),$(slibdir))
default-rpath = $(slibdir):$(libdir)
else
default-rpath = $(libdir)
endif
else
link-libc = $(common-objpfx)libc.a $(gnulib) $(common-objpfx)libc.a
endif
@@ -301,8 +313,10 @@ ifeq ($(elf),yes)
endif
ifdef objpfx
csu-objpfx = $(objpfx)
elf-objpfx = $(objpfx)
else
csu-objpfx = $(..)csu/
elf-objpfx = $(..)elf/
endif
ifeq (yes,$(build-shared))
@@ -311,6 +325,21 @@ rtld-installed-name = ld.so
endif
endif
# How to run a program we just linked with our library.
# The program binary is assumed to be $(word 2,$^).
built-program-file = $(dir $(word 2,$^))$(notdir $(word 2,$^))
ifneq (yes,$(build-shared))
built-program-cmd = $(built-program-file)
else
comma = ,
define built-program-cmd
LD_LIBRARY_PATH=$(common-objdir)$(patsubst -Wl$(comma)-rpath-link=%,:%,\
$(filter -Wl$(comma)-rpath-link=%,\
$(sysdep-LDFLAGS))) \
$(elf-objpfx)ld.so $(built-program-file)
endef
endif
ifndef LD
LD := ld -X
endif
@@ -320,7 +349,7 @@ RANLIB = ranlib
endif
# Extra flags to pass to GCC.
+gccwarn := -Wall -Wwrite-strings -Wno-parentheses -Winline
+gccwarn := -Wall -Wwrite-strings -Wno-parentheses -Winline -Wstrict-prototypes
# This is the program that generates makefile
# dependencies from C source files.
@@ -382,14 +411,18 @@ endif # gcc
# files (including ones given in angle brackets) in the current directory
# and in the parent library source directory.
# `+sysdep-includes' will be defined by Makerules.
+includes = -I. $(filter-out -I,-I$(patsubst %/,%,$(..))) \
+includes = -I. $(filter-out -I,-I$(patsubst %/,%,$(..))) $($(stdio)-include) \
$(includes) $(+sysdep-includes) $(last-includes)
# Since libio has several internal header files, we use a -I instead
# of many little headers in the top level source directory.
libio-include = -I$(..)libio
# These are the variables that the implicit compilation rules use.
CPPFLAGS = $(+includes) $(defines) -include $(..)libc-symbols.h \
$(sysdep-CPPFLAGS) $(CPPFLAGS-$(suffix $@))
override CFLAGS = $(+cflags) $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@))
override CFLAGS = $(+cflags) $(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) \
$(CFLAGS-$(<F))
# This is the macro that the implicit linking rules use.
@@ -417,7 +450,8 @@ ifeq (yes,$(build-profile))
# Under --enable-profile, we will build a static library of profiled objects.
# The profiled object files are named foo.po.
object-suffixes += .po
CFLAGS-.po = -p
CPPFLAGS-.po = -DPROF
CFLAGS-.po = -pg
libtype.po = lib%_p.a
endif
ifeq (yes,$(build-omitfp))
+6 -6
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -36,13 +36,13 @@ mv -f $@.new $@
test ! -d CVS || cvs commit -m'Regenerated: autoconf $(ACFLAGS) $<' $@
endef
configure: configure.in; $(autoconf-it)
%/configure: %/configure.in; $(autoconf-it)
configure: configure.in aclocal.m4; $(autoconf-it)
%/configure: %/configure.in aclocal.m4; $(autoconf-it)
include Makeconfig
ifndef avoid-generated
include $(objpfx)sysd-dirs
-include $(objpfx)sysd-dirs
define \n
@@ -51,8 +51,8 @@ sysdep-subdirs := $(subst $(\n), ,$(sysdep-subdirs))
endif
# These are the subdirectories containing the library source.
subdirs = csu assert ctype locale intl math setjmp signal stdlib \
stdio-common $(stdio) malloc string time dirent grp pwd \
subdirs = csu assert ctype db locale intl math setjmp signal stdlib \
stdio-common $(stdio) malloc string wcsmbs time dirent grp pwd\
posix io termios resource misc socket sysvipc gmon gnulib \
$(wildcard crypt) manual $(sysdep-subdirs) elf
export subdirs := $(subdirs) # Benign, useless in GNU make before 3.63.
+79 -44
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -65,6 +65,15 @@ endif
# Add -I switches to get the right sysdep directories.
# `+includes' in Makeconfig references $(+sysdep-includes).
+sysdep-includes := $(addprefix -I,$(+sysdep_dirs))
# The name of the symbol table archive member. The default is suitable for
# BSD style archives. It can be overridden in sysdep Makefiles when SYSV
# style archive are used.
ifeq (no,$(elf))
ar-symtab-name = __.SYMDEF
else
ar-symtab-name = # The null name is used in ELF archives.
endif
# Include any system-specific makefiles.
@@ -75,17 +84,12 @@ vpath %.h $(subst $(empty) ,:,$(strip $(common-objpfx) \
$(addprefix $(sysdep_dir)/,$(sysdirs)) \
$(..)))
ifeq ($(wildcard $(+sysdir_pfx)sysd-Makefile),)
# Don't do deps until this exists, because it might change the sources list.
no_deps=t
endif
# Some sysdep makefiles use this to distinguish being included here from
# being included individually by a subdir makefile (hurd/Makefile needs this).
in-Makerules := yes
ifndef avoid-generated
include $(+sysdir_pfx)sysd-Makefile
-include $(+sysdir_pfx)sysd-Makefile
ifneq ($(sysd-Makefile-sysdirs),$(sysdirs))
sysd-Makefile-force = FORCE
FORCE:
@@ -104,6 +108,12 @@ $(+sysdir_pfx)sysd-Makefile: $(+sysdir_pfx)config.make $(..)Makerules \
mv -f $@T $@
endif
ifndef sysd-Makefile-done
# Don't do deps until this exists, because it might change the sources list.
no_deps=t
endif
# Reorder before-compile so that mach things come first, and hurd things
# second, before all else. The mach and hurd subdirectories have many
# generated header files which the much of rest of the library depends on,
@@ -197,7 +207,7 @@ endif
# included. It might define inhibit-sysdep-asm, which would affect the
# contents of sysd-rules.
ifdef sysd-Makefile-done
include $(+sysdir_pfx)sysd-rules
-include $(+sysdir_pfx)sysd-rules
ifneq ($(sysd-rules-sysdirs),$(sysdirs))
# The value of $(sysdirs) the sysd-rules was computed for
# differs from the one we are using now. So force a rebuild of sysd-rules.
@@ -231,9 +241,16 @@ $(+sysdir_pfx)sysd-rules: $(+sysdir_pfx)config.make $(..)Makerules \
$(close-check-inhibit-asm) \
echo "\$$(objpfx)%.d: $$dir/%.c \$$(before-compile); \
\$$(+make-deps)"; \
done) > $@T
done; \
echo 'sysd-rules-done = t') > $@T
mv -f $@T $@
ifndef sysd-rules-done
# Don't do deps until this exists, because it provides rules to make the deps.
no_deps=t
endif
ifndef compile-command.S
compile-command.S = $(compile.S) $(OUTPUT_OPTION)
endif
@@ -245,8 +262,10 @@ compile-command.c = $(compile.c) $(OUTPUT_OPTION)
endif
# GCC can grok options after the file name, and it looks nicer that way.
compile.S = $(CC) $< -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS)
compile.c = $(CC) $< -c $(CFLAGS) $(CPPFLAGS)
compile.S = $(CC) $< -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS)
COMPILE.S = $(CC) -c $(CPPFLAGS) -DASSEMBLER $(asm-CPPFLAGS)
COMPILE.s = $(filter-out -pipe,$(CC)) -c $(ASFLAGS)
# We need this for the output to go in the right place. It will default to
# empty if make was configured to work with a cc that can't grok -c and -o
@@ -303,7 +322,7 @@ endif
ifdef +depfiles
ifneq ($(no_deps),t)
include $(+depfiles)
-include $(+depfiles)
endif
endif
@@ -339,12 +358,13 @@ ARFLAGS := r$(verbose)
lib: lib-noranlib $(foreach l,$(libtypes),$(patsubst %,$(common-objpfx)$l,c))
# Pattern rule for libraries: depend on the __.SYMDEF member updated by ranlib.
lib%.a: lib%.a(__.SYMDEF) ;
lib%.a: lib%.a($(ar-symtab-name)) ;
libobjs: $(foreach o,$(object-suffixes),\
$(common-objpfx)$(patsubst %,$(libtype$o),c)(\
$(notdir $(objects:.o=$o))))
lib-noranlib: libobjs $(addprefix $(objpfx),$(install-lib))
lib-noranlib: libobjs
others: $(addprefix $(objpfx),$(install-lib))
ifdef objects
@@ -381,21 +401,18 @@ endif
endif
# Rules to update the __.SYMDEF member with ranlib.
# To consolidate, each flavor library's __.SYMDEF member
# depends on the imaginary intermediate file `symdef.SUFFIX',
# where SUFFIX is that flavor's object suffix; then a pattern rule
# "remakes" symdef.% depending on all the libc.a(foo.%) files in $(objects).
$(common-objpfx)$(patsubst %,$(libtype.o),c)(__.SYMDEF): symdef.o
$(common-objpfx)$(patsubst %,$(libtype.so),c)(__.SYMDEF): symdef.so
$(common-objpfx)$(patsubst %,$(libtype.po),c)(__.SYMDEF): symdef.po
$(common-objpfx)$(patsubst %,$(libtype.go),c)(__.SYMDEF): symdef.go
symdef.%: $(foreach o,$(object-suffixes),\
$(common-objpfx)$(patsubst %,$(libtype$o),c)(\
$(patsubst $(objpfx)%.o,%.%,$(objects)))) \
$(filter subdir_lib,$(firstword $(subdir) subdir_lib))
# The last line above makes it also depend on subdir_lib for the parent.
$(RANLIB) $(common-objpfx)$(patsubst %,$(libtype.$*),c)
# Rules to update the $(ar-symtab-name) member with ranlib,
# one for each object flavor.
define o-iterator-doit
$(common-objpfx)$(patsubst %,$(libtype$o),c)($(ar-symtab-name)): \
$(common-objpfx)$(patsubst %,$(libtype$o),c)(\
$(patsubst $(objpfx)%.o,%$o,$(objects))) \
$(filter subdir_lib,$(firstword $(subdir) subdir_lib)); \
$$(RANLIB) $$(common-objpfx)$$(patsubst %,$$(libtype$o),c)
endef
object-suffixes-left = $(object-suffixes)
include $(o-iterator)
# This makes all the object files.
.PHONY: objects objs
@@ -432,13 +449,11 @@ $(make-target-directory)
$(INSTALL_DATA) $< $@
endef
# Make the target directory if it doesn't exist. Because of make's
# directory cache, this will produce the `mkdir' command when the directory
# already exists, if it didn't exist at the start of the `make' run. The
# `-' prefix ignores errors from mkdir, so there will just be some
# gratuitous but harmless `File exists' messages.
# Make the target directory if it doesn't exist, using the `mkinstalldirs'
# script that does `mkdir -p' even if `mkdir' doesn't support that flag.
define make-target-directory
$(addprefix -mkdir ,$(filter-out $(wildcard $(@D:%/=%)),$(@D:%/=%)))
$(addprefix $(..)mkinstalldirs ,\
$(filter-out $(wildcard $(@D:%/=%)),$(@D:%/=%)))
endef
# Any directory (parent or subdir) that has any object files to build
@@ -448,6 +463,7 @@ ifdef objects
installed-libcs := $(foreach o,$(object-suffixes),\
$(libdir)/$(patsubst %,$(libtype$o),\
$(libprefix)$(libc-name)))
installed-libcs := $(filter-out %_pic.a,$(installed-libcs))
install: $(installed-libcs)
$(installed-libcs): $(libdir)/lib$(libprefix)%: lib
$(make-target-directory)
@@ -466,18 +482,27 @@ endef
install-lib.so := $(filter %.so,$(install-lib:%_pic.a=%.so))
install-lib := $(filter-out %.so %_pic.a,$(install-lib))
ifeq (yes,$(build-shared))
install: $(libdir)/libc.so$(libc.so-version)
install-lib-nosubdir: $(foreach so,$(install-lib.so),\
$(libdir)/$(patsubst $(libprefix)lib%,lib$(libprefix)%,\
$(libprefix)$(so))$($(so)-version))
install-lib.so += libc.so
$(foreach v,$(sort $(foreach so,$(install-lib.so),.so$($(so)-version))),\
install: $(slibdir)/libc.so$(libc.so-version)
$(slibdir)/lib$(libprefix)c.so$(libc.so-version): $(common-objpfx)libc.so
$(do-install-so)
define do-install-so
$(do-install-program)
$(patsubst %,ln -s -f $(@F) $(@D)/$(patsubst %$*.so,%,$(<F))$(libprefix)$*.so,\
$(filter-out %.so,$@))
endef
so-versions := $(sort $(foreach so,$(install-lib.so),.so$($(so)-version)))
$(foreach v,$(so-versions),\
$(libdir)/lib$(libprefix)%$v): $(common-objpfx)lib%.so
$(do-install-program)
$(foreach v,$(sort $(foreach so,$(install-lib.so),.so$($(so)-version))),\
$(do-install-so)
$(foreach v,$(so-versions),\
$(libdir)/$(libprefix)%$v): $(common-objpfx)%.so
$(do-install-program)
$(do-install-so)
endif
ifdef install-bin
@@ -547,7 +572,7 @@ define build-shlib
$(LINK.o) -shared -o $@ $(sysdep-LDFLAGS) $(config-LDFLAGS) \
-Wl,-soname=lib$(libprefix)$(@F:lib%.so=%).so$($(@F)-version) \
$(LDFLAGS.so) $(LDFLAGS-$(@F:lib%.so=%).so) \
-Wl,-rpath-link=$(common-objdir) -Wl,-rpath=$(libdir) \
-Wl,-rpath-link=$(common-objdir) \
-Wl,--whole-archive $^ $(LDLIBS-$(@F:lib%.so=%).so)
endef
@@ -563,6 +588,12 @@ $(common-objpfx)libc.so: $(elfobjdir)/soinit.so \
$(common-objpfx)libc_pic.a \
$(elfobjdir)/sofini.so
$(build-shlib)
ifdef libc.so-version
$(common-objpfx)libc.so$(libc.so-version): $(common-objpfx)libc.so
rm -f $@
ln -s $(<F) $@ || ln $< $@
endif
endif
@@ -586,7 +617,11 @@ check: tests
.PHONY: TAGS
TAGS: distinfo $(..)MakeTAGS
$(MAKE) $(addprefix -f ,$^)
$(MAKE) $(addprefix -f ,$^) $@
$(..)po/%.pot: distinfo $(..)MakeTAGS
$(MAKE) $(addprefix -f ,$^) $@
.PHONY: echo-headers
echo-headers:
@@ -637,7 +672,7 @@ $(common-objpfx)stub-$(subdir): $(+depfiles)
# Make the distribution tar file.
.PHONY: dist
dist: distinfo $(..)Make-dist
dist: distinfo $(..)Make-dist
$(MAKE) -f $< -f $(word 2,$^) $(Make-dist-args)
# Avoid depending on source files found in sysdeps dirs,
@@ -654,7 +689,7 @@ distinfo: Makefile $(..)Makerules
define distinfo-vars
rm -f $@.new
$(foreach var,subdir sources elided-routines headers distribute \
$(foreach var,subdir subdir-dirs sources elided-routines headers distribute \
dont_distribute generated others tests,
echo >> $@.new '$(var) := $($(var))')
echo >> $@.new 'sources := $$(sources) $$(addsuffix .c,$$(elided-routines))'
+56 -7
View File
@@ -1,6 +1,6 @@
GNU C Library NEWS -- history of user-visible changes. 26 July 1995
GNU C Library NEWS -- history of user-visible changes. 2 January 1996
Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
See the end for copying conditions.
Please send GNU C library bug reports to bug-glibc@prep.ai.mit.edu.
@@ -32,6 +32,16 @@ Version 1.10
new header file <link.h> gives access to the internals of the run-time
dynamic linker, `ld.so'.
* The C library now provides the run-time support code for profiling
executables compiled with `-pg'. Programs can control the profiling code
through the interface in <sys/gmon.h>. The profiling code was adapted
from 4.4 BSD-Lite.
* The math code has been replaced with a math library based on fdlibm from
Sun, and modified by JT Conklin with i387 support and by Ian Taylor with
`float' functions. The math functions now reside in a separate library,
so programs using them will need to use `-lm' their linking commands.
* The new functions `strtoq' and `strtouq' parse integer values from
strings, like `strtol' and `strtoul', but they return `long long int' and
`unsigned long long int' values, respectively (64-bit quantities).
@@ -48,7 +58,11 @@ Version 1.10
* The new header <langinfo.h> defines an interface for accessing
various locale-dependent data (using the locale chosen with `setlocale').
* You can now use positional parameter specifications in format strings
* Ulrich Drepper has contributed a new suite of functions for operation on
wide-character and multibyte-character strings; see <wcstr.h> and <mbstr.h>.
These new functions are intended to conform to the ISO C specification.
* You can now use positional parameter specifications in format strings
for the `printf' and `scanf' families of functions. For example,
`printf ("Number %2$d, Mr %1$s\n", "Jones", 6);'' prints
``Number 6, Mr Jones''. This is mainly useful when providing different
@@ -75,7 +89,7 @@ Version 1.10
* The new header file <fts.h> and suite of functions simplify programs that
operate on directory trees. This code comes from 4.4 BSD.
* The resolver code has been updated from the BIND-4.9.3-BETA26 release.
* The resolver code has been updated from the BIND 4.9.3 release.
* The new function `malloc_find_object_address' finds the starting address
of a malloc'd block, given any address within the block. This can be
@@ -123,13 +137,48 @@ Version 1.10
* Ulrich Drepper has contributed new, highly-optimized versions of several
string functions for the i486/Pentium family of processors.
* Ulrich Drepper has updated the Linux-specific code, based largely
* Ulrich Drepper has updated the Linux-specific code, based largely
on work done in Hongjiu Lu's version of GNU libc for Linux.
The GNU library now supports Linux versions 1.3.29 and later,
using the ELF object file format (i[345]86-*-linux).
* Ulrich Drepper has contributed a new set of message catalog functions to
support multiple languages, for use with his new package GNU gettext.
* New header file <values.h> gives SVID-compatible names for <limits.h>
constants.
* Various new macros, declarations, and small header files for compatibility
with 4.4 BSD.
* New function `group_member' is a convenient way to check if a process has
a given effective group ID.
* When using GCC 2.7 and later, the socket functions are now declared in a
special way so that passing an argument of type `struct sockaddr_in *',
`struct sockaddr_ns *', or `struct sockaddr_un *' instead of the generic
`struct sockaddr *' type, does not generate a type-clash warning.
* New function `error' declared in header file <error.h> is a convenient
function for printing error messages and optionally exitting; this is the
canonical function used in GNU programs. The new functions `err', `warn',
and friends in header file <err.h> are the canonical 4.4 BSD interface for
doing the same thing.
* The <glob.h> interface has several new flags from 4.4 BSD that extend the
POSIX.2 `glob' function to do ~ and {...} expansion.
* New function `unsetenv' complements `setenv' for compatibility with 4.4 BSD.
* New function `getsid' returns session ID number on systems that support it.
* We have incorporated the 4.4 BSD `db' library (version 1.85). New header
files <db.h> and <mpool.h> provide a rich set of functions for several
types of simple databases stored in memory and in files, and <ndbm.h> is
an old `ndbm'-compatbile interface using the `db' functions.
* New macro `strdupa' copies a string like `strdup', but uses local stack
space from `alloca' instead of dynamic heap space from `malloc'.
Version 1.09
@@ -362,7 +411,7 @@ Version 1.04
compiler, so the C library should now work with C++ code.
* The header file <bstring.h> is gone. <string.h> now declares bcopy,
bcmp, bzero, and ffs.
bcmp, bzero, and ffs.
* Mike Haertel (of GNU e?grep and malloc fame) has written a new sorting
function which uses the `merge sort' algorithm, and is said to be
@@ -388,7 +437,7 @@ Version 1.04
----------------------------------------------------------------------
Copyright information:
Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
+16 -12
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -38,6 +38,9 @@ export subdir := $(subdir)
.PHONY: all
all: objs lib others
others: $(addprefix $(objpfx),$(extra-objs) \
$(install-lib) $(install-bin) $(install-sbin))
ifneq "$(findstring env,$(origin headers))" ""
headers :=
endif
@@ -55,7 +58,7 @@ endif
include ../Makerules
.PHONY: subdir_lib
subdir_lib: objs lib-noranlib
subdir_lib: lib-noranlib
# Some subdirs need to install a dummy library.
# They can use "$(objpfx)libfnord.a: $(dep-dummy-lib); $(make-dummy-lib)".
@@ -72,7 +75,7 @@ generated := $(generated) dummy.o dummy.c
# This makes all the auxilliary and test programs.
.PHONY: others tests
others: $(addprefix $(objpfx),$(others))
others: $(addprefix $(objpfx),$(others) $(extra-objs))
ifeq ($(cross-compiling),yes)
tests: $(addprefix $(objpfx),$(tests))
else
@@ -80,21 +83,22 @@ tests: $(tests:%=$(objpfx)%.out)
endif
ifneq "$(strip $(others) $(tests))" ""
$(addprefix $(objpfx),$(others) $(tests)): %: %.o $(common-objpfx)libc.a
$(addprefix $(objpfx),$(others) $(tests)): %: %.o \
$(sort $(filter $(common-objpfx)libc%,$(link-libc)))
$(+link)
endif
ifneq "$(strip $(tests))" ""
# These are the implicit rules for making test outputs
# from the test programs and whatever input files are present.
$(objpfx)%.out: $(objpfx)% %.args %.input
$(dir $<)$(notdir $<) `cat $(word 2,$^)` < $(word 3,$^) > $@
$(objpfx)%.out: $(objpfx)% %.args
$(dir $<)$(notdir $<) `cat $(word 2,$^)` > $@
$(objpfx)%.out: $(objpfx)% %.input
$(dir $<)$(notdir $<) < $(word 2,$^) > $@
$(objpfx)%.out: $(objpfx)%
$(dir $<)$(notdir $<) > $@
$(objpfx)%.out: %.args $(objpfx)% %.input
$(built-program-cmd) `cat $(word 1,$^)` < $(word 3,$^) > $@
$(objpfx)%.out: %.args $(objpfx)%
$(built-program-cmd) `cat $(word 1,$^)` > $@
$(objpfx)%.out: %.input $(objpfx)%
$(built-program-cmd) < $(word 1,$^) > $@
$(objpfx)%.out: /dev/null $(objpfx)% # Make it 2nd arg for canned sequence.
$(built-program-cmd) > $@
endif # tests
.PHONY: distclean realclean subdir_distclean subdir_realclean \
+1 -1
View File
@@ -43,7 +43,7 @@ __assert_perror_fail (int errnum,
#endif
/* Print the message. */
(void) fprintf (stderr, "%s%s%s:%u: %s%sUnexpected error: %s.\n",
(void) fprintf (stderr, _("%s%s%s:%u: %s%sUnexpected error: %s.\n"),
__assert_program_name ? __assert_program_name : "",
__assert_program_name ? ": " : "",
file, line,
+2 -2
View File
@@ -38,14 +38,14 @@ CONST char *__assert_program_name;
void
DEFUN(__assert_fail, (assertion, file, line, function),
CONST char *assertion AND
CONST char *file AND unsigned int line AND CONST char *function)
CONST char *file AND unsigned int line AND CONST char *function)
{
#ifdef FATAL_PREPARE
FATAL_PREPARE;
#endif
/* Print the message. */
(void) fprintf (stderr, "%s%s%s:%u: %s%sAssertion `%s' failed.\n",
(void) fprintf (stderr, _("%s%s%s:%u: %s%sAssertion `%s' failed.\n"),
__assert_program_name ? __assert_program_name : "",
__assert_program_name ? ": " : "",
file, line,
+34 -7
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -51,9 +51,10 @@ trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
alpha:OSF1:V*:*)
alpha:OSF1:[VX]*:*)
# After 1.2, OSF1 uses "V1.3" for uname -r.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'`
# After 4.x, OSF1 uses "X4.x" for uname -r.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VX]//'`
exit 0 ;;
alpha:OSF1:*:*)
# 1.2 uses "1.2" for uname -r.
@@ -62,6 +63,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0 ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-cbm-sysv4
exit 0;;
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
@@ -120,6 +124,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
mips:*:5*:RISCos)
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0 ;;
@@ -130,12 +137,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo m88k-motorola-sysv3
exit 0 ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88100 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
@@ -219,7 +231,7 @@ EOF
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[79] ) HP_ARCH=hppa1.1 ;;
9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
@@ -312,6 +324,12 @@ EOF
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
i*:CYGWIN*:*)
echo i386-unknown-cygwin32
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
@@ -319,12 +337,16 @@ EOF
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
if echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
elif echo $ld_help_string | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
elif test "${UNAME_MACHINE}" = "alpha" ; then
echo alpha-unknown-linux ; exit 0
else
@@ -368,6 +390,8 @@ EOF
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-unknown-sysv32
@@ -424,6 +448,9 @@ EOF
echo ns32k-sni-sysv
fi
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
+25 -2
View File
@@ -34,12 +34,22 @@
/* Define to use GNU libio instead of GNU stdio.
This is defined by configure under --enable-libio. */
#undef USE_IN_LIBIO
/* */
/* These symbols might be defined by some sysdeps configures. */
/*
*/
#ifndef _LIBC
/* These symbols might be defined by some sysdeps configures.
They are used only in miscellaneous generator programs, not
in compiling libc itself. */
/* sysdeps/generic/configure.in */
#undef HAVE_PSIGNAL
/* sysdeps/unix/configure.in */
#undef HAVE_STRERROR
/* sysdeps/unix/common/configure.in */
#undef HAVE_SYS_SIGLIST
#undef HAVE__SYS_SIGLIST
@@ -49,3 +59,16 @@
#undef HAVE__CTYPE__
#undef HAVE__CTYPE
#undef HAVE__LOCP
#endif
/*
*/
#ifdef _LIBC
/* The zic and zdump programs need these definitions. */
#define HAVE_STRERROR 1
#endif
Vendored
+55 -19
View File
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -81,13 +81,18 @@ case $os in
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple)
os=
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
@@ -123,19 +128,22 @@ case $os in
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
tahoe | i[3456]86 | i860 | m68k | m68000 | m88k | ns32k | arm \
| arme[lb] | pyramid \
| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
| alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
| powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
| alpha | we32k | ns16k | clipper | i370 | sh \
| powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
| pdp11 | mips64el | mips64orion | mips64orionel \
| sparc)
| sparc | sparclet | sparclite | sparc64)
basic_machine=$basic_machine-unknown
;;
# Object if more than one company name word.
@@ -144,7 +152,7 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
@@ -190,6 +198,14 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-sysv
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
@@ -222,6 +238,10 @@ case $basic_machine in
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
@@ -308,19 +328,19 @@ case $basic_machine in
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[345]86v32)
i[3456]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-sysv32
;;
i[345]86v4*)
i[3456]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-sysv4
;;
i[345]86v)
i[3456]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-sysv
;;
i[345]86sol2)
i[3456]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
os=-solaris2
;;
@@ -419,14 +439,18 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | p6)
# We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
pentium | p5)
basic_machine=i586-intel
;;
pentium-* | p5-* | p6-*)
# We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium
pentiumpro | p6)
basic_machine=i686-intel
;;
pentium-* | p5-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
k5)
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
basic_machine=i586-amd
@@ -633,15 +657,16 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \
| -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigados* | -msdos* | -newsos* | -unicos* | -aos* \
| -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
| -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
| -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* )
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin32* | -pe* | -psos* | -moss* )
# Remember, each alternative MUST END IN *, to match a version number.
;;
-sunos5*)
@@ -668,6 +693,9 @@ case $os in
-ctix* | -uts*)
os=-sysv
;;
-ns2 )
os=-nextstep2
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
@@ -775,6 +803,9 @@ case $basic_machine in
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
@@ -859,6 +890,11 @@ case $basic_machine in
-vxworks*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-aux*)
vendor=apple
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
Vendored
+79 -45
View File
@@ -2,7 +2,7 @@
# From configure.in CVSid
# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.4.2
# Generated automatically using autoconf version 2.7
# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
@@ -14,6 +14,8 @@ ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_help="$ac_help
--with-gmp=DIRECTORY find GMP source code in DIRECTORY (not needed)"
ac_help="$ac_help
--with-gettext=DIR find GNU gettext source code in DIR (not needed)"
ac_help="$ac_help
--with-fp if using floating-point hardware"
ac_help="$ac_help
@@ -71,6 +73,7 @@ mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
ac_prev=
for ac_option
@@ -170,9 +173,11 @@ Directory and file names:
--bindir=DIR user executables in DIR [EPREFIX/bin]
--sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
--libexecdir=DIR program executables in DIR [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data in DIR [PREFIX/share]
--datadir=DIR read-only architecture-independent data in DIR
[PREFIX/share]
--sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com]
--sharedstatedir=DIR modifiable architecture-independent data in DIR
[PREFIX/com]
--localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
--libdir=DIR object code libraries in DIR [EPREFIX/lib]
--includedir=DIR C header files in DIR [PREFIX/include]
@@ -182,7 +187,8 @@ Directory and file names:
--srcdir=DIR find the sources in DIR [configure dir or ..]
--program-prefix=PREFIX prepend PREFIX to installed program names
--program-suffix=SUFFIX append SUFFIX to installed program names
--program-transform-name=PROGRAM run sed PROGRAM on installed program names
--program-transform-name=PROGRAM
run sed PROGRAM on installed program names
EOF
cat << EOF
Host type:
@@ -196,8 +202,10 @@ Features and packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--x-includes=DIR X include files are in DIR
--x-libraries=DIR X library files are in DIR
--enable and --with options recognized:$ac_help
EOF
if test -n "$ac_help"; then
echo "--enable and --with options recognized:$ac_help"
fi
exit 0 ;;
-host | --host | --hos | --ho)
@@ -347,7 +355,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
echo "configure generated by autoconf version 2.4.2"
echo "configure generated by autoconf version 2.7"
exit 0 ;;
-with-* | --with-*)
@@ -393,7 +401,7 @@ EOF
-*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
;;
*)
*)
if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
echo "configure: warning: $ac_option: invalid host type" 1>&2
fi
@@ -512,12 +520,9 @@ fi
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='echo $CPP $CPPFLAGS 1>&5;
$CPP $CPPFLAGS'
ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
@@ -558,6 +563,21 @@ esac
fi
# Check for a --with-gettext argument and set gettext-srcdir in config.make.
# Check whether --with-gettext or --without-gettext was given.
if test "${with_gettext+set}" = set; then
withval="$with_gettext"
case "$with_gettext" in
yes)
{ echo "configure: error: --with-gettext requires an argument; use --with-gettext=DIR" 1>&2; exit 1; } ;;
''|no) ;;
*)
config_vars="$config_vars
gettext-srcdir = $withval" ;;
esac
fi
# Check whether --with-fp or --without-fp was given.
if test "${with_fp+set}" = set; then
@@ -612,9 +632,13 @@ fi
# Check whether --enable-libio or --disable-libio was given.
if test "${enable_libio+set}" = set; then
enableval="$enable_libio"
stdio=libio
if test $enableval = yes; then
stdio=libio
else
stdio=stdio
fi
else
stdio=stdio
stdio=default
fi
@@ -643,16 +667,6 @@ else
fi
echo $ac_n "checking stdio selection""... $ac_c" 1>&4
if test $stdio = libio; then
cat >> confdefs.h <<\EOF
#define USE_IN_LIBIO 1
EOF
fi
echo "$ac_t""$stdio" 1>&4
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
@@ -768,7 +782,7 @@ ostry=$os
while o=`echo $tail | sed 's/\.[^.]*$//'`; test $o != $tail; do
ostry="$ostry /$o"
tail=$o
done
done
o=`echo $tail | sed 's/[0-9]*$//'`
if test $o != $tail; then
ostry="$ostry /$o"
@@ -1005,7 +1019,7 @@ else
ac_cv_prog_CC="$CC" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in gcc; do
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
@@ -1035,7 +1049,7 @@ else
ac_cv_prog_AR="$AR" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in ar; do
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
@@ -1095,7 +1109,7 @@ else
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in :; do
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_RANLIB="ranlib"
@@ -1133,12 +1147,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
#line 1137 "configure"
#line 1151 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
eval "$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:1157: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@@ -1147,12 +1162,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
#line 1151 "configure"
#line 1166 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
eval "$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:1172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
@@ -1201,7 +1217,7 @@ if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&4
else
cat > conftest.$ac_ext <<EOF
#line 1205 "configure"
#line 1221 "configure"
#include "confdefs.h"
#define __need_size_t
#define __need_wchar_t
@@ -1217,7 +1233,7 @@ size_t size; wchar_t wchar;
if (&size == NULL || &wchar == NULL) abort ();
; return 0; }
EOF
if eval $ac_compile; then
if { (eval echo configure:1237: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_friendly_stddef=yes
else
@@ -1324,7 +1340,7 @@ if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&4
else
cat > conftest.$ac_ext <<EOF
#line 1328 "configure"
#line 1344 "configure"
#include "confdefs.h"
int main() { return 0; }
@@ -1333,7 +1349,7 @@ asm (".section .init");
asm (".section .fini");
; return 0; }
EOF
if eval $ac_compile; then
if { (eval echo configure:1353: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
libc_cv_have_initfini=yes
else
@@ -1365,9 +1381,14 @@ for dir in $sysnames; do
echo "$ac_t""running configure fragment for $dir" 1>&4
. $sysdep_dir/$dir/configure
fi
if test -z "$uname"; then
{ test -r $sysdep_dir/$dir/uname.c || test -r $sysdep_dir/$dir/uname.S; } \
&& uname=$dir
if test -r $sysdep_dir/$dir/uname.c ||
test -r $sysdep_dir/$dir/uname.S ||
{ test -r $sysdep_dir/$dir/syscalls.list &&
grep '^uname[ ]' $sysdep_dir/$dir/syscalls.list >/dev/null; }; then
uname=$dir
fi
fi
done
@@ -1424,6 +1445,17 @@ else
config_uname=
fi
echo $ac_n "checking stdio selection""... $ac_c" 1>&4
case $stdio in
libio) cat >> confdefs.h <<\EOF
#define USE_IN_LIBIO 1
EOF
;;
default) stdio=stdio ;;
esac
echo "$ac_t""$stdio" 1>&4
if test $gnu_ld = yes; then
cat >> confdefs.h <<\EOF
@@ -1541,7 +1573,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
echo "$CONFIG_STATUS generated by autoconf version 2.4.2"
echo "$CONFIG_STATUS generated by autoconf version 2.7"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -1553,10 +1585,12 @@ ac_given_srcdir=$srcdir
ac_given_INSTALL="$INSTALL"
trap 'rm -fr `echo "config.make ${config_makefile} ${config_uname} config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF
# Protect against being on the right side of a sed subst in config.status.
sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
# Protect against being on the right side of a sed subst in config.status.
sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@CFLAGS@%$CFLAGS%g
@@ -1580,7 +1614,6 @@ s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@stdio@%$stdio%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
@@ -1602,6 +1635,7 @@ s%@libc_cv_have_initfini@%$libc_cv_have_initfini%g
s%@uname_sysname@%$uname_sysname%g
s%@uname_release@%$uname_release%g
s%@uname_version@%$uname_version%g
s%@stdio@%$stdio%g
s%@gnu_ld@%$gnu_ld%g
s%@gnu_as@%$gnu_as%g
s%@elf@%$elf%g
@@ -1707,7 +1741,7 @@ EOF
# Transform confdefs.h into a sed script conftest.vals that substitutes
# the proper values into config.h.in to produce config.h. And first:
# Protect against being on the right side of a sed subst in config.status.
# Protect against being on the right side of a sed subst in config.status.
# Protect against being in an unquoted here document in config.status.
rm -f conftest.vals
cat > conftest.hdr <<\EOF
+36 -11
View File
@@ -18,6 +18,19 @@ yes) AC_MSG_ERROR(--with-gmp requires an argument; use --with-gmp=DIRECTORY) ;;
gmp-srcdir = $withval" ;;
esac
])
# Check for a --with-gettext argument and set gettext-srcdir in config.make.
AC_ARG_WITH(gettext, dnl
--with-gettext=DIR find GNU gettext source code in DIR (not needed),
[dnl
case "$with_gettext" in
yes)
AC_MSG_ERROR(--with-gettext requires an argument; use --with-gettext=DIR) ;;
''|no) ;;
*)
config_vars="$config_vars
gettext-srcdir = $withval" ;;
esac
])
dnl Arguments to specify presence of other packages/features.
AC_ARG_WITH(fp, dnl
@@ -42,7 +55,12 @@ AC_ARG_WITH(weak-symbols, dnl
AC_ARG_ENABLE(libio, dnl
[ --enable-libio build in GNU libio instead of GNU stdio],
stdio=libio, stdio=stdio)
[if test $enableval = yes; then
stdio=libio
else
stdio=stdio
fi],
stdio=default)
dnl Arguments to enable or disable building the shared, profiled, and
dnl -fomit-frame-pointer libraries.
@@ -56,13 +74,6 @@ AC_ARG_ENABLE(omitfp, dnl
[ --enable-omitfp build undebuggable optimized library [default=no]],
omitfp=$enableval, omitfp=no)
AC_MSG_CHECKING(stdio selection)
AC_SUBST(stdio)
if test $stdio = libio; then
AC_DEFINE(USE_IN_LIBIO)
fi
AC_MSG_RESULT($stdio)
AC_CANONICAL_HOST
# We keep the original values in `$config_*' and never modify them, so we
# can write them unchanged into config.make. Everything else uses
@@ -133,7 +144,7 @@ ostry=$os
while o=`echo $tail | sed 's/\.[^.]*$//'`; test $o != $tail; do
ostry="$ostry /$o"
tail=$o
done
done
o=`echo $tail | sed 's/[0-9]*$//'`
if test $o != $tail; then
ostry="$ostry /$o"
@@ -407,10 +418,16 @@ for dir in $sysnames; do
AC_MSG_RESULT(running configure fragment for $dir)
. $sysdep_dir/$dir/configure
fi
[
if test -z "$uname"; then
{ test -r $sysdep_dir/$dir/uname.c || test -r $sysdep_dir/$dir/uname.S; } \
&& uname=$dir
if test -r $sysdep_dir/$dir/uname.c ||
test -r $sysdep_dir/$dir/uname.S ||
{ test -r $sysdep_dir/$dir/syscalls.list &&
grep '^uname[ ]' $sysdep_dir/$dir/syscalls.list >/dev/null; }; then
uname=$dir
fi
fi
]dnl
done
AC_LINK_FILES(`echo $libc_link_sources`, `echo $libc_link_dests`)
@@ -473,6 +490,14 @@ else
config_uname=
fi
AC_MSG_CHECKING(stdio selection)
AC_SUBST(stdio)
case $stdio in
libio) AC_DEFINE(USE_IN_LIBIO) ;;
default) stdio=stdio ;;
esac
AC_MSG_RESULT($stdio)
AC_SUBST(gnu_ld) AC_SUBST(gnu_as) AC_SUBST(elf) AC_SUBST(weak)
if test $gnu_ld = yes; then
AC_DEFINE(HAVE_GNU_LD)
+5 -3
View File
@@ -1,6 +1,6 @@
# Makefile for csu code for GNU C library.
# Copyright (C) 1995 Free Software Foundation, Inc.
# Copyright (C) 1995, 1996 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
@@ -48,7 +48,7 @@ start-installed-name = crt0.o
else
# In the ELF universe, crt0.o is called crt1.o, and there are
# In the ELF universe, crt0.o is called crt1.o, and there are
# some additional bizarre files.
start-installed-name = crt1.o
have-initfini = yes
@@ -57,6 +57,8 @@ endif
ifeq (yes,$(have-initfini))
CPPFLAGS += -DHAVE_INITFINI
# These are the special initializer/finalizer files. They are always the
# first and last file in the link. crti.o ... crtn.o define the global
# "functions" _init and _fini to run the .init and .fini sections.
@@ -77,7 +79,7 @@ define initfini
-rm -f $(objpfx)crtcommon.tmp
(echo 'cat > crtcommon.tmp <<\EOF_common'; \
$(CC) $< $(CPPFLAGS) $(CFLAGS) \
-finhibit-size-directive -g0 -S -o -; \
-fPIC -finhibit-size-directive -g0 -S -o -; \
echo 'EOF_common') | (cd $(@D); $(SHELL))
cat $(objpfx)crtcommon.tmp >> $(objpfx)crti.s-new
cat $(objpfx)crtcommon.tmp >> $(objpfx)crtn.s-new
+13 -10
View File
@@ -1,5 +1,5 @@
/* Code to enable profiling at program startup.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 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
@@ -23,19 +23,22 @@ Cambridge, MA 02139, USA. */
#include <unistd.h>
/* Beginning and end of our code segment. */
extern void _start (), etext ();
/* These functions are defined in gmon/gmon.c;
they do all the work of setting up and cleaning up profiling. */
extern void monstartup (u_long, u_long);
extern void _mcleanup (void);
extern void _start (void), etext (void);
#ifndef HAVE_INITFINI
/* This function gets called at startup by the normal constructor
mechanism. We link this file together with start.o to produce gcrt1.o,
so this constructor will be first in the list. */
static void gmon_start (void) __attribute__ ((constructor));
static void
gmon_start (void)
void __gmon_start__ (void) __attribute__ ((constructor));
#else
/* In ELF and COFF, we cannot use the normal constructor mechanism to call
__gmon_start__ because gcrt1.o appears before crtbegin.o in the link.
Instead crti.o calls it specially (see initfini.c). */
#endif
void
__gmon_start__ (void)
{
/* Start keeping profiling records. */
monstartup ((u_long) &_start, (u_long) &etext);
+12
View File
@@ -59,10 +59,22 @@ cp crti.s-new crtn.s-new");
/* Append the .init prologue to crti.s-new. */
asm ("cat >> crti.s-new <<\\EOF.crti.init");
SECTION (".init")
void
_init (void)
{
/* We cannot use the normal constructor mechanism in gcrt1.o because it
appears before crtbegin.o in the link, so the header elt of .ctors
would come after the elt for __gmon_start__. One approach is for
gcrt1.o to reference a symbol which would be defined by some library
module which has a constructor; but then user code's constructors
would come first, and not be profiled. */
extern void __gmon_start__ (void) __attribute__ ((weak));
weak_symbol (__gmon_start__)
if (__gmon_start__)
__gmon_start__ ();
/* End the here document containing the .init prologue code.
Then fetch the .section directive just written and append that
to crtn.s-new, followed by the function epilogue. */
+5
View File
@@ -0,0 +1,5 @@
*.gz *.Z *.tar *.tgz
=*
TODO COPYING* AUTHORS copyr-* copying.*
glibc-*
distinfo
+28
View File
@@ -0,0 +1,28 @@
# Makefile for 4.4BSD db code in GNU C library.
# This code is taken verbatim from the BSD db 1.85 package. Only this
# Makefile and compat.h were written for GNU libc, and the header files
# moved up to this directory.
subdir = db
subdir-dirs = btree db hash mpool recno
vpath %.c $(subdir-dirs)
routines := bt_close bt_conv bt_debug bt_delete bt_get bt_open bt_overflow \
bt_page bt_put bt_search bt_seq bt_split bt_utils \
db \
hash hash_bigkey hash_buf hash_func hash_log2 hash_page \
ndbm \
mpool \
rec_close rec_delete rec_get rec_open rec_put rec_search \
rec_seq rec_utils
headers := db.h mpool.h ndbm.h
distribute := compat.h \
btree/btree.h btree/extern.h \
hash/extern.h hash/hash.h hash/page.h \
recno/extern.h recno/recno.h
include ../Rules
CPPFLAGS += -D__DBINTERFACE_PRIVATE
+182
View File
@@ -0,0 +1,182 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_close.c 8.7 (Berkeley) 8/17/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <db.h>
#include "btree.h"
static int bt_meta __P((BTREE *));
/*
* BT_CLOSE -- Close a btree.
*
* Parameters:
* dbp: pointer to access method
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_close(dbp)
DB *dbp;
{
BTREE *t;
int fd;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Sync the tree. */
if (__bt_sync(dbp, 0) == RET_ERROR)
return (RET_ERROR);
/* Close the memory pool. */
if (mpool_close(t->bt_mp) == RET_ERROR)
return (RET_ERROR);
/* Free random memory. */
if (t->bt_cursor.key.data != NULL) {
free(t->bt_cursor.key.data);
t->bt_cursor.key.size = 0;
t->bt_cursor.key.data = NULL;
}
if (t->bt_rkey.data) {
free(t->bt_rkey.data);
t->bt_rkey.size = 0;
t->bt_rkey.data = NULL;
}
if (t->bt_rdata.data) {
free(t->bt_rdata.data);
t->bt_rdata.size = 0;
t->bt_rdata.data = NULL;
}
fd = t->bt_fd;
free(t);
free(dbp);
return (close(fd) ? RET_ERROR : RET_SUCCESS);
}
/*
* BT_SYNC -- sync the btree to disk.
*
* Parameters:
* dbp: pointer to access method
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__bt_sync(dbp, flags)
const DB *dbp;
u_int flags;
{
BTREE *t;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Sync doesn't currently take any flags. */
if (flags != 0) {
errno = EINVAL;
return (RET_ERROR);
}
if (F_ISSET(t, B_INMEM | B_RDONLY) || !F_ISSET(t, B_MODIFIED))
return (RET_SUCCESS);
if (F_ISSET(t, B_METADIRTY) && bt_meta(t) == RET_ERROR)
return (RET_ERROR);
if ((status = mpool_sync(t->bt_mp)) == RET_SUCCESS)
F_CLR(t, B_MODIFIED);
return (status);
}
/*
* BT_META -- write the tree meta data to disk.
*
* Parameters:
* t: tree
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
bt_meta(t)
BTREE *t;
{
BTMETA m;
void *p;
if ((p = mpool_get(t->bt_mp, P_META, 0)) == NULL)
return (RET_ERROR);
/* Fill in metadata. */
m.magic = BTREEMAGIC;
m.version = BTREEVERSION;
m.psize = t->bt_psize;
m.free = t->bt_free;
m.nrecs = t->bt_nrecs;
m.flags = F_ISSET(t, SAVEMETA);
memmove(p, &m, sizeof(BTMETA));
mpool_put(t->bt_mp, p, MPOOL_DIRTY);
return (RET_SUCCESS);
}
+221
View File
@@ -0,0 +1,221 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_conv.c 8.5 (Berkeley) 8/17/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <db.h>
#include "btree.h"
static void mswap __P((PAGE *));
/*
* __BT_BPGIN, __BT_BPGOUT --
* Convert host-specific number layout to/from the host-independent
* format stored on disk.
*
* Parameters:
* t: tree
* pg: page number
* h: page to convert
*/
void
__bt_pgin(t, pg, pp)
void *t;
pgno_t pg;
void *pp;
{
PAGE *h;
indx_t i, top;
u_char flags;
char *p;
if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
return;
if (pg == P_META) {
mswap(pp);
return;
}
h = pp;
M_32_SWAP(h->pgno);
M_32_SWAP(h->prevpg);
M_32_SWAP(h->nextpg);
M_32_SWAP(h->flags);
M_16_SWAP(h->lower);
M_16_SWAP(h->upper);
top = NEXTINDEX(h);
if ((h->flags & P_TYPE) == P_BINTERNAL)
for (i = 0; i < top; i++) {
M_16_SWAP(h->linp[i]);
p = (char *)GETBINTERNAL(h, i);
P_32_SWAP(p);
p += sizeof(u_int32_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
if (*(u_char *)p & P_BIGKEY) {
p += sizeof(u_char);
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
}
else if ((h->flags & P_TYPE) == P_BLEAF)
for (i = 0; i < top; i++) {
M_16_SWAP(h->linp[i]);
p = (char *)GETBLEAF(h, i);
P_32_SWAP(p);
p += sizeof(u_int32_t);
P_32_SWAP(p);
p += sizeof(u_int32_t);
flags = *(u_char *)p;
if (flags & (P_BIGKEY | P_BIGDATA)) {
p += sizeof(u_char);
if (flags & P_BIGKEY) {
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
if (flags & P_BIGDATA) {
p += sizeof(u_int32_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
}
}
}
void
__bt_pgout(t, pg, pp)
void *t;
pgno_t pg;
void *pp;
{
PAGE *h;
indx_t i, top;
u_char flags;
char *p;
if (!F_ISSET(((BTREE *)t), B_NEEDSWAP))
return;
if (pg == P_META) {
mswap(pp);
return;
}
h = pp;
top = NEXTINDEX(h);
if ((h->flags & P_TYPE) == P_BINTERNAL)
for (i = 0; i < top; i++) {
p = (char *)GETBINTERNAL(h, i);
P_32_SWAP(p);
p += sizeof(u_int32_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
if (*(u_char *)p & P_BIGKEY) {
p += sizeof(u_char);
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
M_16_SWAP(h->linp[i]);
}
else if ((h->flags & P_TYPE) == P_BLEAF)
for (i = 0; i < top; i++) {
p = (char *)GETBLEAF(h, i);
P_32_SWAP(p);
p += sizeof(u_int32_t);
P_32_SWAP(p);
p += sizeof(u_int32_t);
flags = *(u_char *)p;
if (flags & (P_BIGKEY | P_BIGDATA)) {
p += sizeof(u_char);
if (flags & P_BIGKEY) {
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
if (flags & P_BIGDATA) {
p += sizeof(u_int32_t);
P_32_SWAP(p);
p += sizeof(pgno_t);
P_32_SWAP(p);
}
}
M_16_SWAP(h->linp[i]);
}
M_32_SWAP(h->pgno);
M_32_SWAP(h->prevpg);
M_32_SWAP(h->nextpg);
M_32_SWAP(h->flags);
M_16_SWAP(h->lower);
M_16_SWAP(h->upper);
}
/*
* MSWAP -- Actually swap the bytes on the meta page.
*
* Parameters:
* p: page to convert
*/
static void
mswap(pg)
PAGE *pg;
{
char *p;
p = (char *)pg;
P_32_SWAP(p); /* magic */
p += sizeof(u_int32_t);
P_32_SWAP(p); /* version */
p += sizeof(u_int32_t);
P_32_SWAP(p); /* psize */
p += sizeof(u_int32_t);
P_32_SWAP(p); /* free */
p += sizeof(u_int32_t);
P_32_SWAP(p); /* nrecs */
p += sizeof(u_int32_t);
P_32_SWAP(p); /* flags */
p += sizeof(u_int32_t);
}
+329
View File
@@ -0,0 +1,329 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_debug.c 8.5 (Berkeley) 8/17/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
#ifdef DEBUG
/*
* BT_DUMP -- Dump the tree
*
* Parameters:
* dbp: pointer to the DB
*/
void
__bt_dump(dbp)
DB *dbp;
{
BTREE *t;
PAGE *h;
pgno_t i;
char *sep;
t = dbp->internal;
(void)fprintf(stderr, "%s: pgsz %d",
F_ISSET(t, B_INMEM) ? "memory" : "disk", t->bt_psize);
if (F_ISSET(t, R_RECNO))
(void)fprintf(stderr, " keys %lu", t->bt_nrecs);
#undef X
#define X(flag, name) \
if (F_ISSET(t, flag)) { \
(void)fprintf(stderr, "%s%s", sep, name); \
sep = ", "; \
}
if (t->flags != 0) {
sep = " flags (";
X(R_FIXLEN, "FIXLEN");
X(B_INMEM, "INMEM");
X(B_NODUPS, "NODUPS");
X(B_RDONLY, "RDONLY");
X(R_RECNO, "RECNO");
X(B_METADIRTY,"METADIRTY");
(void)fprintf(stderr, ")\n");
}
#undef X
for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
__bt_dpage(h);
(void)mpool_put(t->bt_mp, h, 0);
}
}
/*
* BT_DMPAGE -- Dump the meta page
*
* Parameters:
* h: pointer to the PAGE
*/
void
__bt_dmpage(h)
PAGE *h;
{
BTMETA *m;
char *sep;
m = (BTMETA *)h;
(void)fprintf(stderr, "magic %lx\n", m->magic);
(void)fprintf(stderr, "version %lu\n", m->version);
(void)fprintf(stderr, "psize %lu\n", m->psize);
(void)fprintf(stderr, "free %lu\n", m->free);
(void)fprintf(stderr, "nrecs %lu\n", m->nrecs);
(void)fprintf(stderr, "flags %lu", m->flags);
#undef X
#define X(flag, name) \
if (m->flags & flag) { \
(void)fprintf(stderr, "%s%s", sep, name); \
sep = ", "; \
}
if (m->flags) {
sep = " (";
X(B_NODUPS, "NODUPS");
X(R_RECNO, "RECNO");
(void)fprintf(stderr, ")");
}
}
/*
* BT_DNPAGE -- Dump the page
*
* Parameters:
* n: page number to dump.
*/
void
__bt_dnpage(dbp, pgno)
DB *dbp;
pgno_t pgno;
{
BTREE *t;
PAGE *h;
t = dbp->internal;
if ((h = mpool_get(t->bt_mp, pgno, 0)) != NULL) {
__bt_dpage(h);
(void)mpool_put(t->bt_mp, h, 0);
}
}
/*
* BT_DPAGE -- Dump the page
*
* Parameters:
* h: pointer to the PAGE
*/
void
__bt_dpage(h)
PAGE *h;
{
BINTERNAL *bi;
BLEAF *bl;
RINTERNAL *ri;
RLEAF *rl;
indx_t cur, top;
char *sep;
(void)fprintf(stderr, " page %d: (", h->pgno);
#undef X
#define X(flag, name) \
if (h->flags & flag) { \
(void)fprintf(stderr, "%s%s", sep, name); \
sep = ", "; \
}
sep = "";
X(P_BINTERNAL, "BINTERNAL") /* types */
X(P_BLEAF, "BLEAF")
X(P_RINTERNAL, "RINTERNAL") /* types */
X(P_RLEAF, "RLEAF")
X(P_OVERFLOW, "OVERFLOW")
X(P_PRESERVE, "PRESERVE");
(void)fprintf(stderr, ")\n");
#undef X
(void)fprintf(stderr, "\tprev %2d next %2d", h->prevpg, h->nextpg);
if (h->flags & P_OVERFLOW)
return;
top = NEXTINDEX(h);
(void)fprintf(stderr, " lower %3d upper %3d nextind %d\n",
h->lower, h->upper, top);
for (cur = 0; cur < top; cur++) {
(void)fprintf(stderr, "\t[%03d] %4d ", cur, h->linp[cur]);
switch (h->flags & P_TYPE) {
case P_BINTERNAL:
bi = GETBINTERNAL(h, cur);
(void)fprintf(stderr,
"size %03d pgno %03d", bi->ksize, bi->pgno);
if (bi->flags & P_BIGKEY)
(void)fprintf(stderr, " (indirect)");
else if (bi->ksize)
(void)fprintf(stderr,
" {%.*s}", (int)bi->ksize, bi->bytes);
break;
case P_RINTERNAL:
ri = GETRINTERNAL(h, cur);
(void)fprintf(stderr, "entries %03d pgno %03d",
ri->nrecs, ri->pgno);
break;
case P_BLEAF:
bl = GETBLEAF(h, cur);
if (bl->flags & P_BIGKEY)
(void)fprintf(stderr,
"big key page %lu size %u/",
*(pgno_t *)bl->bytes,
*(u_int32_t *)(bl->bytes + sizeof(pgno_t)));
else if (bl->ksize)
(void)fprintf(stderr, "%s/", bl->bytes);
if (bl->flags & P_BIGDATA)
(void)fprintf(stderr,
"big data page %lu size %u",
*(pgno_t *)(bl->bytes + bl->ksize),
*(u_int32_t *)(bl->bytes + bl->ksize +
sizeof(pgno_t)));
else if (bl->dsize)
(void)fprintf(stderr, "%.*s",
(int)bl->dsize, bl->bytes + bl->ksize);
break;
case P_RLEAF:
rl = GETRLEAF(h, cur);
if (rl->flags & P_BIGDATA)
(void)fprintf(stderr,
"big data page %lu size %u",
*(pgno_t *)rl->bytes,
*(u_int32_t *)(rl->bytes + sizeof(pgno_t)));
else if (rl->dsize)
(void)fprintf(stderr,
"%.*s", (int)rl->dsize, rl->bytes);
break;
}
(void)fprintf(stderr, "\n");
}
}
#endif
#ifdef STATISTICS
/*
* BT_STAT -- Gather/print the tree statistics
*
* Parameters:
* dbp: pointer to the DB
*/
void
__bt_stat(dbp)
DB *dbp;
{
extern u_long bt_cache_hit, bt_cache_miss, bt_pfxsaved, bt_rootsplit;
extern u_long bt_sortsplit, bt_split;
BTREE *t;
PAGE *h;
pgno_t i, pcont, pinternal, pleaf;
u_long ifree, lfree, nkeys;
int levels;
t = dbp->internal;
pcont = pinternal = pleaf = 0;
nkeys = ifree = lfree = 0;
for (i = P_ROOT; (h = mpool_get(t->bt_mp, i, 0)) != NULL; ++i) {
switch (h->flags & P_TYPE) {
case P_BINTERNAL:
case P_RINTERNAL:
++pinternal;
ifree += h->upper - h->lower;
break;
case P_BLEAF:
case P_RLEAF:
++pleaf;
lfree += h->upper - h->lower;
nkeys += NEXTINDEX(h);
break;
case P_OVERFLOW:
++pcont;
break;
}
(void)mpool_put(t->bt_mp, h, 0);
}
/* Count the levels of the tree. */
for (i = P_ROOT, levels = 0 ;; ++levels) {
h = mpool_get(t->bt_mp, i, 0);
if (h->flags & (P_BLEAF|P_RLEAF)) {
if (levels == 0)
levels = 1;
(void)mpool_put(t->bt_mp, h, 0);
break;
}
i = F_ISSET(t, R_RECNO) ?
GETRINTERNAL(h, 0)->pgno :
GETBINTERNAL(h, 0)->pgno;
(void)mpool_put(t->bt_mp, h, 0);
}
(void)fprintf(stderr, "%d level%s with %ld keys",
levels, levels == 1 ? "" : "s", nkeys);
if (F_ISSET(t, R_RECNO))
(void)fprintf(stderr, " (%ld header count)", t->bt_nrecs);
(void)fprintf(stderr,
"\n%lu pages (leaf %ld, internal %ld, overflow %ld)\n",
pinternal + pleaf + pcont, pleaf, pinternal, pcont);
(void)fprintf(stderr, "%ld cache hits, %ld cache misses\n",
bt_cache_hit, bt_cache_miss);
(void)fprintf(stderr, "%ld splits (%ld root splits, %ld sort splits)\n",
bt_split, bt_rootsplit, bt_sortsplit);
pleaf *= t->bt_psize - BTDATAOFF;
if (pleaf)
(void)fprintf(stderr,
"%.0f%% leaf fill (%ld bytes used, %ld bytes free)\n",
((double)(pleaf - lfree) / pleaf) * 100,
pleaf - lfree, lfree);
pinternal *= t->bt_psize - BTDATAOFF;
if (pinternal)
(void)fprintf(stderr,
"%.0f%% internal fill (%ld bytes used, %ld bytes free\n",
((double)(pinternal - ifree) / pinternal) * 100,
pinternal - ifree, ifree);
if (bt_pfxsaved)
(void)fprintf(stderr, "prefix checking removed %lu bytes.\n",
bt_pfxsaved);
}
#endif
+657
View File
@@ -0,0 +1,657 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_delete.c 8.13 (Berkeley) 7/28/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <db.h>
#include "btree.h"
static int __bt_bdelete __P((BTREE *, const DBT *));
static int __bt_curdel __P((BTREE *, const DBT *, PAGE *, u_int));
static int __bt_pdelete __P((BTREE *, PAGE *));
static int __bt_relink __P((BTREE *, PAGE *));
static int __bt_stkacq __P((BTREE *, PAGE **, CURSOR *));
/*
* __bt_delete
* Delete the item(s) referenced by a key.
*
* Return RET_SPECIAL if the key is not found.
*/
int
__bt_delete(dbp, key, flags)
const DB *dbp;
const DBT *key;
u_int flags;
{
BTREE *t;
CURSOR *c;
PAGE *h;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Check for change to a read-only tree. */
if (F_ISSET(t, B_RDONLY)) {
errno = EPERM;
return (RET_ERROR);
}
switch (flags) {
case 0:
status = __bt_bdelete(t, key);
break;
case R_CURSOR:
/*
* If flags is R_CURSOR, delete the cursor. Must already
* have started a scan and not have already deleted it.
*/
c = &t->bt_cursor;
if (F_ISSET(c, CURS_INIT)) {
if (F_ISSET(c, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
return (RET_ERROR);
/*
* If the page is about to be emptied, we'll need to
* delete it, which means we have to acquire a stack.
*/
if (NEXTINDEX(h) == 1)
if (__bt_stkacq(t, &h, &t->bt_cursor))
return (RET_ERROR);
status = __bt_dleaf(t, NULL, h, c->pg.index);
if (NEXTINDEX(h) == 0 && status == RET_SUCCESS) {
if (__bt_pdelete(t, h))
return (RET_ERROR);
} else
mpool_put(t->bt_mp,
h, status == RET_SUCCESS ? MPOOL_DIRTY : 0);
break;
}
/* FALLTHROUGH */
default:
errno = EINVAL;
return (RET_ERROR);
}
if (status == RET_SUCCESS)
F_SET(t, B_MODIFIED);
return (status);
}
/*
* __bt_stkacq --
* Acquire a stack so we can delete a cursor entry.
*
* Parameters:
* t: tree
* hp: pointer to current, pinned PAGE pointer
* c: pointer to the cursor
*
* Returns:
* 0 on success, 1 on failure
*/
static int
__bt_stkacq(t, hp, c)
BTREE *t;
PAGE **hp;
CURSOR *c;
{
BINTERNAL *bi;
EPG *e;
EPGNO *parent;
PAGE *h;
indx_t index;
pgno_t pgno;
recno_t nextpg, prevpg;
int exact, level;
/*
* Find the first occurrence of the key in the tree. Toss the
* currently locked page so we don't hit an already-locked page.
*/
h = *hp;
mpool_put(t->bt_mp, h, 0);
if ((e = __bt_search(t, &c->key, &exact)) == NULL)
return (1);
h = e->page;
/* See if we got it in one shot. */
if (h->pgno == c->pg.pgno)
goto ret;
/*
* Move right, looking for the page. At each move we have to move
* up the stack until we don't have to move to the next page. If
* we have to change pages at an internal level, we have to fix the
* stack back up.
*/
while (h->pgno != c->pg.pgno) {
if ((nextpg = h->nextpg) == P_INVALID)
break;
mpool_put(t->bt_mp, h, 0);
/* Move up the stack. */
for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
/* Get the parent page. */
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
return (1);
/* Move to the next index. */
if (parent->index != NEXTINDEX(h) - 1) {
index = parent->index + 1;
BT_PUSH(t, h->pgno, index);
break;
}
mpool_put(t->bt_mp, h, 0);
}
/* Restore the stack. */
while (level--) {
/* Push the next level down onto the stack. */
bi = GETBINTERNAL(h, index);
pgno = bi->pgno;
BT_PUSH(t, pgno, 0);
/* Lose the currently pinned page. */
mpool_put(t->bt_mp, h, 0);
/* Get the next level down. */
if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
return (1);
index = 0;
}
mpool_put(t->bt_mp, h, 0);
if ((h = mpool_get(t->bt_mp, nextpg, 0)) == NULL)
return (1);
}
if (h->pgno == c->pg.pgno)
goto ret;
/* Reacquire the original stack. */
mpool_put(t->bt_mp, h, 0);
if ((e = __bt_search(t, &c->key, &exact)) == NULL)
return (1);
h = e->page;
/*
* Move left, looking for the page. At each move we have to move
* up the stack until we don't have to change pages to move to the
* next page. If we have to change pages at an internal level, we
* have to fix the stack back up.
*/
while (h->pgno != c->pg.pgno) {
if ((prevpg = h->prevpg) == P_INVALID)
break;
mpool_put(t->bt_mp, h, 0);
/* Move up the stack. */
for (level = 0; (parent = BT_POP(t)) != NULL; ++level) {
/* Get the parent page. */
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
return (1);
/* Move to the next index. */
if (parent->index != 0) {
index = parent->index - 1;
BT_PUSH(t, h->pgno, index);
break;
}
mpool_put(t->bt_mp, h, 0);
}
/* Restore the stack. */
while (level--) {
/* Push the next level down onto the stack. */
bi = GETBINTERNAL(h, index);
pgno = bi->pgno;
/* Lose the currently pinned page. */
mpool_put(t->bt_mp, h, 0);
/* Get the next level down. */
if ((h = mpool_get(t->bt_mp, pgno, 0)) == NULL)
return (1);
index = NEXTINDEX(h) - 1;
BT_PUSH(t, pgno, index);
}
mpool_put(t->bt_mp, h, 0);
if ((h = mpool_get(t->bt_mp, prevpg, 0)) == NULL)
return (1);
}
ret: mpool_put(t->bt_mp, h, 0);
return ((*hp = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL);
}
/*
* __bt_bdelete --
* Delete all key/data pairs matching the specified key.
*
* Parameters:
* t: tree
* key: key to delete
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
static int
__bt_bdelete(t, key)
BTREE *t;
const DBT *key;
{
EPG *e;
PAGE *h;
int deleted, exact, redo;
deleted = 0;
/* Find any matching record; __bt_search pins the page. */
loop: if ((e = __bt_search(t, key, &exact)) == NULL)
return (deleted ? RET_SUCCESS : RET_ERROR);
if (!exact) {
mpool_put(t->bt_mp, e->page, 0);
return (deleted ? RET_SUCCESS : RET_SPECIAL);
}
/*
* Delete forward, then delete backward, from the found key. If
* there are duplicates and we reach either side of the page, do
* the key search again, so that we get them all.
*/
redo = 0;
h = e->page;
do {
if (__bt_dleaf(t, key, h, e->index)) {
mpool_put(t->bt_mp, h, 0);
return (RET_ERROR);
}
if (F_ISSET(t, B_NODUPS)) {
if (NEXTINDEX(h) == 0) {
if (__bt_pdelete(t, h))
return (RET_ERROR);
} else
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
deleted = 1;
} while (e->index < NEXTINDEX(h) && __bt_cmp(t, key, e) == 0);
/* Check for right-hand edge of the page. */
if (e->index == NEXTINDEX(h))
redo = 1;
/* Delete from the key to the beginning of the page. */
while (e->index-- > 0) {
if (__bt_cmp(t, key, e) != 0)
break;
if (__bt_dleaf(t, key, h, e->index) == RET_ERROR) {
mpool_put(t->bt_mp, h, 0);
return (RET_ERROR);
}
if (e->index == 0)
redo = 1;
}
/* Check for an empty page. */
if (NEXTINDEX(h) == 0) {
if (__bt_pdelete(t, h))
return (RET_ERROR);
goto loop;
}
/* Put the page. */
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
if (redo)
goto loop;
return (RET_SUCCESS);
}
/*
* __bt_pdelete --
* Delete a single page from the tree.
*
* Parameters:
* t: tree
* h: leaf page
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*
* Side-effects:
* mpool_put's the page
*/
static int
__bt_pdelete(t, h)
BTREE *t;
PAGE *h;
{
BINTERNAL *bi;
PAGE *pg;
EPGNO *parent;
indx_t cnt, index, *ip, offset;
u_int32_t nksize;
char *from;
/*
* Walk the parent page stack -- a LIFO stack of the pages that were
* traversed when we searched for the page where the delete occurred.
* Each stack entry is a page number and a page index offset. The
* offset is for the page traversed on the search. We've just deleted
* a page, so we have to delete the key from the parent page.
*
* If the delete from the parent page makes it empty, this process may
* continue all the way up the tree. We stop if we reach the root page
* (which is never deleted, it's just not worth the effort) or if the
* delete does not empty the page.
*/
while ((parent = BT_POP(t)) != NULL) {
/* Get the parent page. */
if ((pg = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
return (RET_ERROR);
index = parent->index;
bi = GETBINTERNAL(pg, index);
/* Free any overflow pages. */
if (bi->flags & P_BIGKEY &&
__ovfl_delete(t, bi->bytes) == RET_ERROR) {
mpool_put(t->bt_mp, pg, 0);
return (RET_ERROR);
}
/*
* Free the parent if it has only the one key and it's not the
* root page. If it's the rootpage, turn it back into an empty
* leaf page.
*/
if (NEXTINDEX(pg) == 1)
if (pg->pgno == P_ROOT) {
pg->lower = BTDATAOFF;
pg->upper = t->bt_psize;
pg->flags = P_BLEAF;
} else {
if (__bt_relink(t, pg) || __bt_free(t, pg))
return (RET_ERROR);
continue;
}
else {
/* Pack remaining key items at the end of the page. */
nksize = NBINTERNAL(bi->ksize);
from = (char *)pg + pg->upper;
memmove(from + nksize, from, (char *)bi - from);
pg->upper += nksize;
/* Adjust indices' offsets, shift the indices down. */
offset = pg->linp[index];
for (cnt = index, ip = &pg->linp[0]; cnt--; ++ip)
if (ip[0] < offset)
ip[0] += nksize;
for (cnt = NEXTINDEX(pg) - index; --cnt; ++ip)
ip[0] = ip[1] < offset ? ip[1] + nksize : ip[1];
pg->lower -= sizeof(indx_t);
}
mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
break;
}
/* Free the leaf page, as long as it wasn't the root. */
if (h->pgno == P_ROOT) {
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
return (__bt_relink(t, h) || __bt_free(t, h));
}
/*
* __bt_dleaf --
* Delete a single record from a leaf page.
*
* Parameters:
* t: tree
* key: referenced key
* h: page
* index: index on page to delete
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__bt_dleaf(t, key, h, index)
BTREE *t;
const DBT *key;
PAGE *h;
u_int index;
{
BLEAF *bl;
indx_t cnt, *ip, offset;
u_int32_t nbytes;
void *to;
char *from;
/* If this record is referenced by the cursor, delete the cursor. */
if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
!F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index == index &&
__bt_curdel(t, key, h, index))
return (RET_ERROR);
/* If the entry uses overflow pages, make them available for reuse. */
to = bl = GETBLEAF(h, index);
if (bl->flags & P_BIGKEY && __ovfl_delete(t, bl->bytes) == RET_ERROR)
return (RET_ERROR);
if (bl->flags & P_BIGDATA &&
__ovfl_delete(t, bl->bytes + bl->ksize) == RET_ERROR)
return (RET_ERROR);
/* Pack the remaining key/data items at the end of the page. */
nbytes = NBLEAF(bl);
from = (char *)h + h->upper;
memmove(from + nbytes, from, (char *)to - from);
h->upper += nbytes;
/* Adjust the indices' offsets, shift the indices down. */
offset = h->linp[index];
for (cnt = index, ip = &h->linp[0]; cnt--; ++ip)
if (ip[0] < offset)
ip[0] += nbytes;
for (cnt = NEXTINDEX(h) - index; --cnt; ++ip)
ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
h->lower -= sizeof(indx_t);
/* If the cursor is on this page, adjust it as necessary. */
if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
!F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index > index)
--t->bt_cursor.pg.index;
return (RET_SUCCESS);
}
/*
* __bt_curdel --
* Delete the cursor.
*
* Parameters:
* t: tree
* key: referenced key (or NULL)
* h: page
* index: index on page to delete
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
static int
__bt_curdel(t, key, h, index)
BTREE *t;
const DBT *key;
PAGE *h;
u_int index;
{
CURSOR *c;
EPG e;
PAGE *pg;
int curcopy, status;
/*
* If there are duplicates, move forward or backward to one.
* Otherwise, copy the key into the cursor area.
*/
c = &t->bt_cursor;
F_CLR(c, CURS_AFTER | CURS_BEFORE | CURS_ACQUIRE);
curcopy = 0;
if (!F_ISSET(t, B_NODUPS)) {
/*
* We're going to have to do comparisons. If we weren't
* provided a copy of the key, i.e. the user is deleting
* the current cursor position, get one.
*/
if (key == NULL) {
e.page = h;
e.index = index;
if ((status = __bt_ret(t, &e,
&c->key, &c->key, NULL, NULL, 1)) != RET_SUCCESS)
return (status);
curcopy = 1;
key = &c->key;
}
/* Check previous key, if not at the beginning of the page. */
if (index > 0) {
e.page = h;
e.index = index - 1;
if (__bt_cmp(t, key, &e) == 0) {
F_SET(c, CURS_BEFORE);
goto dup2;
}
}
/* Check next key, if not at the end of the page. */
if (index < NEXTINDEX(h) - 1) {
e.page = h;
e.index = index + 1;
if (__bt_cmp(t, key, &e) == 0) {
F_SET(c, CURS_AFTER);
goto dup2;
}
}
/* Check previous key if at the beginning of the page. */
if (index == 0 && h->prevpg != P_INVALID) {
if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
return (RET_ERROR);
e.page = pg;
e.index = NEXTINDEX(pg) - 1;
if (__bt_cmp(t, key, &e) == 0) {
F_SET(c, CURS_BEFORE);
goto dup1;
}
mpool_put(t->bt_mp, pg, 0);
}
/* Check next key if at the end of the page. */
if (index == NEXTINDEX(h) - 1 && h->nextpg != P_INVALID) {
if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
return (RET_ERROR);
e.page = pg;
e.index = 0;
if (__bt_cmp(t, key, &e) == 0) {
F_SET(c, CURS_AFTER);
dup1: mpool_put(t->bt_mp, pg, 0);
dup2: c->pg.pgno = e.page->pgno;
c->pg.index = e.index;
return (RET_SUCCESS);
}
mpool_put(t->bt_mp, pg, 0);
}
}
e.page = h;
e.index = index;
if (curcopy || (status =
__bt_ret(t, &e, &c->key, &c->key, NULL, NULL, 1)) == RET_SUCCESS) {
F_SET(c, CURS_ACQUIRE);
return (RET_SUCCESS);
}
return (status);
}
/*
* __bt_relink --
* Link around a deleted page.
*
* Parameters:
* t: tree
* h: page to be deleted
*/
static int
__bt_relink(t, h)
BTREE *t;
PAGE *h;
{
PAGE *pg;
if (h->nextpg != P_INVALID) {
if ((pg = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
return (RET_ERROR);
pg->prevpg = h->prevpg;
mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
}
if (h->prevpg != P_INVALID) {
if ((pg = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
return (RET_ERROR);
pg->nextpg = h->nextpg;
mpool_put(t->bt_mp, pg, MPOOL_DIRTY);
}
return (0);
}
+105
View File
@@ -0,0 +1,105 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_get.c 8.6 (Berkeley) 7/20/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <db.h>
#include "btree.h"
/*
* __BT_GET -- Get a record from the btree.
*
* Parameters:
* dbp: pointer to access method
* key: key to find
* data: data to return
* flag: currently unused
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
int
__bt_get(dbp, key, data, flags)
const DB *dbp;
const DBT *key;
DBT *data;
u_int flags;
{
BTREE *t;
EPG *e;
int exact, status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Get currently doesn't take any flags. */
if (flags) {
errno = EINVAL;
return (RET_ERROR);
}
if ((e = __bt_search(t, key, &exact)) == NULL)
return (RET_ERROR);
if (!exact) {
mpool_put(t->bt_mp, e->page, 0);
return (RET_SPECIAL);
}
status = __bt_ret(t, e, NULL, NULL, data, &t->bt_rdata, 0);
/*
* If the user is doing concurrent access, we copied the
* key/data, toss the page.
*/
if (F_ISSET(t, B_DB_LOCK))
mpool_put(t->bt_mp, e->page, 0);
else
t->bt_pinned = e->page;
return (status);
}
+456
View File
@@ -0,0 +1,456 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_open.c 8.10 (Berkeley) 8/17/94";
#endif /* LIBC_SCCS and not lint */
/*
* Implementation of btree access method for 4.4BSD.
*
* The design here was originally based on that of the btree access method
* used in the Postgres database system at UC Berkeley. This implementation
* is wholly independent of the Postgres code.
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <db.h>
#include "btree.h"
#ifdef DEBUG
#undef MINPSIZE
#define MINPSIZE 128
#endif
static int byteorder __P((void));
static int nroot __P((BTREE *));
static int tmp __P((void));
/*
* __BT_OPEN -- Open a btree.
*
* Creates and fills a DB struct, and calls the routine that actually
* opens the btree.
*
* Parameters:
* fname: filename (NULL for in-memory trees)
* flags: open flag bits
* mode: open permission bits
* b: BTREEINFO pointer
*
* Returns:
* NULL on failure, pointer to DB on success.
*
*/
DB *
__bt_open(fname, flags, mode, openinfo, dflags)
const char *fname;
int flags, mode, dflags;
const BTREEINFO *openinfo;
{
struct stat sb;
BTMETA m;
BTREE *t;
BTREEINFO b;
DB *dbp;
pgno_t ncache;
ssize_t nr;
int machine_lorder;
t = NULL;
/*
* Intention is to make sure all of the user's selections are okay
* here and then use them without checking. Can't be complete, since
* we don't know the right page size, lorder or flags until the backing
* file is opened. Also, the file's page size can cause the cachesize
* to change.
*/
machine_lorder = byteorder();
if (openinfo) {
b = *openinfo;
/* Flags: R_DUP. */
if (b.flags & ~(R_DUP))
goto einval;
/*
* Page size must be indx_t aligned and >= MINPSIZE. Default
* page size is set farther on, based on the underlying file
* transfer size.
*/
if (b.psize &&
(b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
b.psize & sizeof(indx_t) - 1))
goto einval;
/* Minimum number of keys per page; absolute minimum is 2. */
if (b.minkeypage) {
if (b.minkeypage < 2)
goto einval;
} else
b.minkeypage = DEFMINKEYPAGE;
/* If no comparison, use default comparison and prefix. */
if (b.compare == NULL) {
b.compare = __bt_defcmp;
if (b.prefix == NULL)
b.prefix = __bt_defpfx;
}
if (b.lorder == 0)
b.lorder = machine_lorder;
} else {
b.compare = __bt_defcmp;
b.cachesize = 0;
b.flags = 0;
b.lorder = machine_lorder;
b.minkeypage = DEFMINKEYPAGE;
b.prefix = __bt_defpfx;
b.psize = 0;
}
/* Check for the ubiquitous PDP-11. */
if (b.lorder != BIG_ENDIAN && b.lorder != LITTLE_ENDIAN)
goto einval;
/* Allocate and initialize DB and BTREE structures. */
if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
goto err;
memset(t, 0, sizeof(BTREE));
t->bt_fd = -1; /* Don't close unopened fd on error. */
t->bt_lorder = b.lorder;
t->bt_order = NOT;
t->bt_cmp = b.compare;
t->bt_pfx = b.prefix;
t->bt_rfd = -1;
if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
goto err;
memset(t->bt_dbp, 0, sizeof(DB));
if (t->bt_lorder != machine_lorder)
F_SET(t, B_NEEDSWAP);
dbp->type = DB_BTREE;
dbp->internal = t;
dbp->close = __bt_close;
dbp->del = __bt_delete;
dbp->fd = __bt_fd;
dbp->get = __bt_get;
dbp->put = __bt_put;
dbp->seq = __bt_seq;
dbp->sync = __bt_sync;
/*
* If no file name was supplied, this is an in-memory btree and we
* open a backing temporary file. Otherwise, it's a disk-based tree.
*/
if (fname) {
switch (flags & O_ACCMODE) {
case O_RDONLY:
F_SET(t, B_RDONLY);
break;
case O_RDWR:
break;
case O_WRONLY:
default:
goto einval;
}
if ((t->bt_fd = open(fname, flags, mode)) < 0)
goto err;
} else {
if ((flags & O_ACCMODE) != O_RDWR)
goto einval;
if ((t->bt_fd = tmp()) == -1)
goto err;
F_SET(t, B_INMEM);
}
if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
goto err;
if (fstat(t->bt_fd, &sb))
goto err;
if (sb.st_size) {
if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
goto err;
if (nr != sizeof(BTMETA))
goto eftype;
/*
* Read in the meta-data. This can change the notion of what
* the lorder, page size and flags are, and, when the page size
* changes, the cachesize value can change too. If the user
* specified the wrong byte order for an existing database, we
* don't bother to return an error, we just clear the NEEDSWAP
* bit.
*/
if (m.magic == BTREEMAGIC)
F_CLR(t, B_NEEDSWAP);
else {
F_SET(t, B_NEEDSWAP);
M_32_SWAP(m.magic);
M_32_SWAP(m.version);
M_32_SWAP(m.psize);
M_32_SWAP(m.free);
M_32_SWAP(m.nrecs);
M_32_SWAP(m.flags);
}
if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
goto eftype;
if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
m.psize & sizeof(indx_t) - 1)
goto eftype;
if (m.flags & ~SAVEMETA)
goto eftype;
b.psize = m.psize;
F_SET(t, m.flags);
t->bt_free = m.free;
t->bt_nrecs = m.nrecs;
} else {
/*
* Set the page size to the best value for I/O to this file.
* Don't overflow the page offset type.
*/
if (b.psize == 0) {
b.psize = sb.st_blksize;
if (b.psize < MINPSIZE)
b.psize = MINPSIZE;
if (b.psize > MAX_PAGE_OFFSET + 1)
b.psize = MAX_PAGE_OFFSET + 1;
}
/* Set flag if duplicates permitted. */
if (!(b.flags & R_DUP))
F_SET(t, B_NODUPS);
t->bt_free = P_INVALID;
t->bt_nrecs = 0;
F_SET(t, B_METADIRTY);
}
t->bt_psize = b.psize;
/* Set the cache size; must be a multiple of the page size. */
if (b.cachesize && b.cachesize & b.psize - 1)
b.cachesize += (~b.cachesize & b.psize - 1) + 1;
if (b.cachesize < b.psize * MINCACHE)
b.cachesize = b.psize * MINCACHE;
/* Calculate number of pages to cache. */
ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
/*
* The btree data structure requires that at least two keys can fit on
* a page, but other than that there's no fixed requirement. The user
* specified a minimum number per page, and we translated that into the
* number of bytes a key/data pair can use before being placed on an
* overflow page. This calculation includes the page header, the size
* of the index referencing the leaf item and the size of the leaf item
* structure. Also, don't let the user specify a minkeypage such that
* a key/data pair won't fit even if both key and data are on overflow
* pages.
*/
t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
(sizeof(indx_t) + NBLEAFDBT(0, 0));
if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
t->bt_ovflsize =
NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
/* Initialize the buffer pool. */
if ((t->bt_mp =
mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
goto err;
if (!F_ISSET(t, B_INMEM))
mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
/* Create a root page if new tree. */
if (nroot(t) == RET_ERROR)
goto err;
/* Global flags. */
if (dflags & DB_LOCK)
F_SET(t, B_DB_LOCK);
if (dflags & DB_SHMEM)
F_SET(t, B_DB_SHMEM);
if (dflags & DB_TXN)
F_SET(t, B_DB_TXN);
return (dbp);
einval: errno = EINVAL;
goto err;
eftype: errno = EFTYPE;
goto err;
err: if (t) {
if (t->bt_dbp)
free(t->bt_dbp);
if (t->bt_fd != -1)
(void)close(t->bt_fd);
free(t);
}
return (NULL);
}
/*
* NROOT -- Create the root of a new tree.
*
* Parameters:
* t: tree
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
nroot(t)
BTREE *t;
{
PAGE *meta, *root;
pgno_t npg;
if ((meta = mpool_get(t->bt_mp, 0, 0)) != NULL) {
mpool_put(t->bt_mp, meta, 0);
return (RET_SUCCESS);
}
if (errno != EINVAL) /* It's OK to not exist. */
return (RET_ERROR);
errno = 0;
if ((meta = mpool_new(t->bt_mp, &npg)) == NULL)
return (RET_ERROR);
if ((root = mpool_new(t->bt_mp, &npg)) == NULL)
return (RET_ERROR);
if (npg != P_ROOT)
return (RET_ERROR);
root->pgno = npg;
root->prevpg = root->nextpg = P_INVALID;
root->lower = BTDATAOFF;
root->upper = t->bt_psize;
root->flags = P_BLEAF;
memset(meta, 0, t->bt_psize);
mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
mpool_put(t->bt_mp, root, MPOOL_DIRTY);
return (RET_SUCCESS);
}
static int
tmp()
{
sigset_t set, oset;
int fd;
const char *envtmp;
char *path;
static const char fmt[] = "%s/bt.XXXXXX";
size_t n;
envtmp = getenv("TMPDIR");
if (!envtmp)
envtmp = "/tmp";
n = strlen (envtmp) + sizeof fmt;
#ifdef __GNUC__
path = __builtin_alloca(n);
#else
path = malloc(n);
#endif
(void)snprintf(path, n, fmt, envtmp ? envtmp : "/tmp");
(void)sigfillset(&set);
(void)sigprocmask(SIG_BLOCK, &set, &oset);
if ((fd = mkstemp(path)) != -1)
(void)unlink(path);
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
#ifndef __GNUC__
free(path);
#endif
return(fd);
}
static int
byteorder()
{
u_int32_t x;
u_char *p;
x = 0x01020304;
p = (u_char *)&x;
switch (*p) {
case 1:
return (BIG_ENDIAN);
case 4:
return (LITTLE_ENDIAN);
default:
return (0);
}
}
int
__bt_fd(dbp)
const DB *dbp;
{
BTREE *t;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* In-memory database can't have a file descriptor. */
if (F_ISSET(t, B_INMEM)) {
errno = ENOENT;
return (-1);
}
return (t->bt_fd);
}
+228
View File
@@ -0,0 +1,228 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_overflow.c 8.5 (Berkeley) 7/16/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
/*
* Big key/data code.
*
* Big key and data entries are stored on linked lists of pages. The initial
* reference is byte string stored with the key or data and is the page number
* and size. The actual record is stored in a chain of pages linked by the
* nextpg field of the PAGE header.
*
* The first page of the chain has a special property. If the record is used
* by an internal page, it cannot be deleted and the P_PRESERVE bit will be set
* in the header.
*
* XXX
* A single DBT is written to each chain, so a lot of space on the last page
* is wasted. This is a fairly major bug for some data sets.
*/
/*
* __OVFL_GET -- Get an overflow key/data item.
*
* Parameters:
* t: tree
* p: pointer to { pgno_t, u_int32_t }
* buf: storage address
* bufsz: storage size
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__ovfl_get(t, p, ssz, buf, bufsz)
BTREE *t;
void *p;
size_t *ssz;
void **buf;
size_t *bufsz;
{
PAGE *h;
pgno_t pg;
size_t nb, plen;
u_int32_t sz;
memmove(&pg, p, sizeof(pgno_t));
memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
*ssz = sz;
#ifdef DEBUG
if (pg == P_INVALID || sz == 0)
abort();
#endif
/* Make the buffer bigger as necessary. */
if (*bufsz < sz) {
*buf = (char *)(*buf == NULL ? malloc(sz) : realloc(*buf, sz));
if (*buf == NULL)
return (RET_ERROR);
*bufsz = sz;
}
/*
* Step through the linked list of pages, copying the data on each one
* into the buffer. Never copy more than the data's length.
*/
plen = t->bt_psize - BTDATAOFF;
for (p = *buf;; p = (char *)p + nb, pg = h->nextpg) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
nb = MIN(sz, plen);
memmove(p, (char *)h + BTDATAOFF, nb);
mpool_put(t->bt_mp, h, 0);
if ((sz -= nb) == 0)
break;
}
return (RET_SUCCESS);
}
/*
* __OVFL_PUT -- Store an overflow key/data item.
*
* Parameters:
* t: tree
* data: DBT to store
* pgno: storage page number
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__ovfl_put(t, dbt, pg)
BTREE *t;
const DBT *dbt;
pgno_t *pg;
{
PAGE *h, *last;
void *p;
pgno_t npg;
size_t nb, plen;
u_int32_t sz;
/*
* Allocate pages and copy the key/data record into them. Store the
* number of the first page in the chain.
*/
plen = t->bt_psize - BTDATAOFF;
for (last = NULL, p = dbt->data, sz = dbt->size;;
p = (char *)p + plen, last = h) {
if ((h = __bt_new(t, &npg)) == NULL)
return (RET_ERROR);
h->pgno = npg;
h->nextpg = h->prevpg = P_INVALID;
h->flags = P_OVERFLOW;
h->lower = h->upper = 0;
nb = MIN(sz, plen);
memmove((char *)h + BTDATAOFF, p, nb);
if (last) {
last->nextpg = h->pgno;
mpool_put(t->bt_mp, last, MPOOL_DIRTY);
} else
*pg = h->pgno;
if ((sz -= nb) == 0) {
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
break;
}
}
return (RET_SUCCESS);
}
/*
* __OVFL_DELETE -- Delete an overflow chain.
*
* Parameters:
* t: tree
* p: pointer to { pgno_t, u_int32_t }
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__ovfl_delete(t, p)
BTREE *t;
void *p;
{
PAGE *h;
pgno_t pg;
size_t plen;
u_int32_t sz;
memmove(&pg, p, sizeof(pgno_t));
memmove(&sz, (char *)p + sizeof(pgno_t), sizeof(u_int32_t));
#ifdef DEBUG
if (pg == P_INVALID || sz == 0)
abort();
#endif
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
/* Don't delete chains used by internal pages. */
if (h->flags & P_PRESERVE) {
mpool_put(t->bt_mp, h, 0);
return (RET_SUCCESS);
}
/* Step through the chain, calling the free routine for each page. */
for (plen = t->bt_psize - BTDATAOFF;; sz -= plen) {
pg = h->nextpg;
__bt_free(t, h);
if (sz <= plen)
break;
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
}
return (RET_SUCCESS);
}
+98
View File
@@ -0,0 +1,98 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_page.c 8.3 (Berkeley) 7/14/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
#include <db.h>
#include "btree.h"
/*
* __bt_free --
* Put a page on the freelist.
*
* Parameters:
* t: tree
* h: page to free
*
* Returns:
* RET_ERROR, RET_SUCCESS
*
* Side-effect:
* mpool_put's the page.
*/
int
__bt_free(t, h)
BTREE *t;
PAGE *h;
{
/* Insert the page at the head of the free list. */
h->prevpg = P_INVALID;
h->nextpg = t->bt_free;
t->bt_free = h->pgno;
/* Make sure the page gets written back. */
return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
}
/*
* __bt_new --
* Get a new page, preferably from the freelist.
*
* Parameters:
* t: tree
* npg: storage for page number.
*
* Returns:
* Pointer to a page, NULL on error.
*/
PAGE *
__bt_new(t, npg)
BTREE *t;
pgno_t *npg;
{
PAGE *h;
if (t->bt_free != P_INVALID &&
(h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
*npg = t->bt_free;
t->bt_free = h->nextpg;
return (h);
}
return (mpool_new(t->bt_mp, npg));
}
+320
View File
@@ -0,0 +1,320 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_put.c 8.8 (Berkeley) 7/26/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
static EPG *bt_fast __P((BTREE *, const DBT *, const DBT *, int *));
/*
* __BT_PUT -- Add a btree item to the tree.
*
* Parameters:
* dbp: pointer to access method
* key: key
* data: data
* flag: R_NOOVERWRITE
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is already in the
* tree and R_NOOVERWRITE specified.
*/
int
__bt_put(dbp, key, data, flags)
const DB *dbp;
DBT *key;
const DBT *data;
u_int flags;
{
BTREE *t;
DBT tkey, tdata;
EPG *e;
PAGE *h;
indx_t index, nxtindex;
pgno_t pg;
u_int32_t nbytes;
int dflags, exact, status;
char *dest, db[NOVFLSIZE], kb[NOVFLSIZE];
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Check for change to a read-only tree. */
if (F_ISSET(t, B_RDONLY)) {
errno = EPERM;
return (RET_ERROR);
}
switch (flags) {
case 0:
case R_NOOVERWRITE:
break;
case R_CURSOR:
/*
* If flags is R_CURSOR, put the cursor. Must already
* have started a scan and not have already deleted it.
*/
if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
!F_ISSET(&t->bt_cursor,
CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE))
break;
/* FALLTHROUGH */
default:
errno = EINVAL;
return (RET_ERROR);
}
/*
* If the key/data pair won't fit on a page, store it on overflow
* pages. Only put the key on the overflow page if the pair are
* still too big after moving the data to an overflow page.
*
* XXX
* If the insert fails later on, the overflow pages aren't recovered.
*/
dflags = 0;
if (key->size + data->size > t->bt_ovflsize) {
if (key->size > t->bt_ovflsize) {
storekey: if (__ovfl_put(t, key, &pg) == RET_ERROR)
return (RET_ERROR);
tkey.data = kb;
tkey.size = NOVFLSIZE;
memmove(kb, &pg, sizeof(pgno_t));
memmove(kb + sizeof(pgno_t),
&key->size, sizeof(u_int32_t));
dflags |= P_BIGKEY;
key = &tkey;
}
if (key->size + data->size > t->bt_ovflsize) {
if (__ovfl_put(t, data, &pg) == RET_ERROR)
return (RET_ERROR);
tdata.data = db;
tdata.size = NOVFLSIZE;
memmove(db, &pg, sizeof(pgno_t));
memmove(db + sizeof(pgno_t),
&data->size, sizeof(u_int32_t));
dflags |= P_BIGDATA;
data = &tdata;
}
if (key->size + data->size > t->bt_ovflsize)
goto storekey;
}
/* Replace the cursor. */
if (flags == R_CURSOR) {
if ((h = mpool_get(t->bt_mp, t->bt_cursor.pg.pgno, 0)) == NULL)
return (RET_ERROR);
index = t->bt_cursor.pg.index;
goto delete;
}
/*
* Find the key to delete, or, the location at which to insert.
* Bt_fast and __bt_search both pin the returned page.
*/
if (t->bt_order == NOT || (e = bt_fast(t, key, data, &exact)) == NULL)
if ((e = __bt_search(t, key, &exact)) == NULL)
return (RET_ERROR);
h = e->page;
index = e->index;
/*
* Add the key/data pair to the tree. If an identical key is already
* in the tree, and R_NOOVERWRITE is set, an error is returned. If
* R_NOOVERWRITE is not set, the key is either added (if duplicates are
* permitted) or an error is returned.
*/
switch (flags) {
case R_NOOVERWRITE:
if (!exact)
break;
mpool_put(t->bt_mp, h, 0);
return (RET_SPECIAL);
default:
if (!exact || !F_ISSET(t, B_NODUPS))
break;
/*
* !!!
* Note, the delete may empty the page, so we need to put a
* new entry into the page immediately.
*/
delete: if (__bt_dleaf(t, key, h, index) == RET_ERROR) {
mpool_put(t->bt_mp, h, 0);
return (RET_ERROR);
}
break;
}
/*
* If not enough room, or the user has put a ceiling on the number of
* keys permitted in the page, split the page. The split code will
* insert the key and data and unpin the current page. If inserting
* into the offset array, shift the pointers up.
*/
nbytes = NBLEAFDBT(key->size, data->size);
if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
if ((status = __bt_split(t, h, key,
data, dflags, nbytes, index)) != RET_SUCCESS)
return (status);
goto success;
}
if (index < (nxtindex = NEXTINDEX(h)))
memmove(h->linp + index + 1, h->linp + index,
(nxtindex - index) * sizeof(indx_t));
h->lower += sizeof(indx_t);
h->linp[index] = h->upper -= nbytes;
dest = (char *)h + h->upper;
WR_BLEAF(dest, key, data, dflags);
/* If the cursor is on this page, adjust it as necessary. */
if (F_ISSET(&t->bt_cursor, CURS_INIT) &&
!F_ISSET(&t->bt_cursor, CURS_ACQUIRE) &&
t->bt_cursor.pg.pgno == h->pgno && t->bt_cursor.pg.index >= index)
++t->bt_cursor.pg.index;
if (t->bt_order == NOT)
if (h->nextpg == P_INVALID) {
if (index == NEXTINDEX(h) - 1) {
t->bt_order = FORWARD;
t->bt_last.index = index;
t->bt_last.pgno = h->pgno;
}
} else if (h->prevpg == P_INVALID) {
if (index == 0) {
t->bt_order = BACK;
t->bt_last.index = 0;
t->bt_last.pgno = h->pgno;
}
}
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
success:
if (flags == R_SETCURSOR)
__bt_setcur(t, e->page->pgno, e->index);
F_SET(t, B_MODIFIED);
return (RET_SUCCESS);
}
#ifdef STATISTICS
u_long bt_cache_hit, bt_cache_miss;
#endif
/*
* BT_FAST -- Do a quick check for sorted data.
*
* Parameters:
* t: tree
* key: key to insert
*
* Returns:
* EPG for new record or NULL if not found.
*/
static EPG *
bt_fast(t, key, data, exactp)
BTREE *t;
const DBT *key, *data;
int *exactp;
{
PAGE *h;
u_int32_t nbytes;
int cmp;
if ((h = mpool_get(t->bt_mp, t->bt_last.pgno, 0)) == NULL) {
t->bt_order = NOT;
return (NULL);
}
t->bt_cur.page = h;
t->bt_cur.index = t->bt_last.index;
/*
* If won't fit in this page or have too many keys in this page,
* have to search to get split stack.
*/
nbytes = NBLEAFDBT(key->size, data->size);
if (h->upper - h->lower < nbytes + sizeof(indx_t))
goto miss;
if (t->bt_order == FORWARD) {
if (t->bt_cur.page->nextpg != P_INVALID)
goto miss;
if (t->bt_cur.index != NEXTINDEX(h) - 1)
goto miss;
if ((cmp = __bt_cmp(t, key, &t->bt_cur)) < 0)
goto miss;
t->bt_last.index = cmp ? ++t->bt_cur.index : t->bt_cur.index;
} else {
if (t->bt_cur.page->prevpg != P_INVALID)
goto miss;
if (t->bt_cur.index != 0)
goto miss;
if ((cmp = __bt_cmp(t, key, &t->bt_cur)) > 0)
goto miss;
t->bt_last.index = 0;
}
*exactp = cmp == 0;
#ifdef STATISTICS
++bt_cache_hit;
#endif
return (&t->bt_cur);
miss:
#ifdef STATISTICS
++bt_cache_miss;
#endif
t->bt_order = NOT;
mpool_put(t->bt_mp, h, 0);
return (NULL);
}
+213
View File
@@ -0,0 +1,213 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_search.c 8.8 (Berkeley) 7/31/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <stdio.h>
#include <db.h>
#include "btree.h"
static int __bt_snext __P((BTREE *, PAGE *, const DBT *, int *));
static int __bt_sprev __P((BTREE *, PAGE *, const DBT *, int *));
/*
* __bt_search --
* Search a btree for a key.
*
* Parameters:
* t: tree to search
* key: key to find
* exactp: pointer to exact match flag
*
* Returns:
* The EPG for matching record, if any, or the EPG for the location
* of the key, if it were inserted into the tree, is entered into
* the bt_cur field of the tree. A pointer to the field is returned.
*/
EPG *
__bt_search(t, key, exactp)
BTREE *t;
const DBT *key;
int *exactp;
{
PAGE *h;
indx_t base, index, lim;
pgno_t pg;
int cmp;
BT_CLR(t);
for (pg = P_ROOT;;) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (NULL);
/* Do a binary search on the current page. */
t->bt_cur.page = h;
for (base = 0, lim = NEXTINDEX(h); lim; lim >>= 1) {
t->bt_cur.index = index = base + (lim >> 1);
if ((cmp = __bt_cmp(t, key, &t->bt_cur)) == 0) {
if (h->flags & P_BLEAF) {
*exactp = 1;
return (&t->bt_cur);
}
goto next;
}
if (cmp > 0) {
base = index + 1;
--lim;
}
}
/*
* If it's a leaf page, we're almost done. If no duplicates
* are allowed, or we have an exact match, we're done. Else,
* it's possible that there were matching keys on this page,
* which later deleted, and we're on a page with no matches
* while there are matches on other pages. If at the start or
* end of a page, check the adjacent page.
*/
if (h->flags & P_BLEAF) {
if (!F_ISSET(t, B_NODUPS)) {
if (base == 0 &&
h->prevpg != P_INVALID &&
__bt_sprev(t, h, key, exactp))
return (&t->bt_cur);
if (base == NEXTINDEX(h) &&
h->nextpg != P_INVALID &&
__bt_snext(t, h, key, exactp))
return (&t->bt_cur);
}
*exactp = 0;
t->bt_cur.index = base;
return (&t->bt_cur);
}
/*
* No match found. Base is the smallest index greater than
* key and may be zero or a last + 1 index. If it's non-zero,
* decrement by one, and record the internal page which should
* be a parent page for the key. If a split later occurs, the
* inserted page will be to the right of the saved page.
*/
index = base ? base - 1 : base;
next: BT_PUSH(t, h->pgno, index);
pg = GETBINTERNAL(h, index)->pgno;
mpool_put(t->bt_mp, h, 0);
}
}
/*
* __bt_snext --
* Check for an exact match after the key.
*
* Parameters:
* t: tree
* h: current page
* key: key
* exactp: pointer to exact match flag
*
* Returns:
* If an exact match found.
*/
static int
__bt_snext(t, h, key, exactp)
BTREE *t;
PAGE *h;
const DBT *key;
int *exactp;
{
EPG e;
/*
* Get the next page. The key is either an exact
* match, or not as good as the one we already have.
*/
if ((e.page = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL)
return (0);
e.index = 0;
if (__bt_cmp(t, key, &e) == 0) {
mpool_put(t->bt_mp, h, 0);
t->bt_cur = e;
*exactp = 1;
return (1);
}
mpool_put(t->bt_mp, e.page, 0);
return (0);
}
/*
* __bt_sprev --
* Check for an exact match before the key.
*
* Parameters:
* t: tree
* h: current page
* key: key
* exactp: pointer to exact match flag
*
* Returns:
* If an exact match found.
*/
static int
__bt_sprev(t, h, key, exactp)
BTREE *t;
PAGE *h;
const DBT *key;
int *exactp;
{
EPG e;
/*
* Get the previous page. The key is either an exact
* match, or not as good as the one we already have.
*/
if ((e.page = mpool_get(t->bt_mp, h->prevpg, 0)) == NULL)
return (0);
e.index = NEXTINDEX(e.page) - 1;
if (__bt_cmp(t, key, &e) == 0) {
mpool_put(t->bt_mp, h, 0);
t->bt_cur = e;
*exactp = 1;
return (1);
}
mpool_put(t->bt_mp, e.page, 0);
return (0);
}
+460
View File
@@ -0,0 +1,460 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_seq.c 8.7 (Berkeley) 7/20/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <db.h>
#include "btree.h"
static int __bt_first __P((BTREE *, const DBT *, EPG *, int *));
static int __bt_seqadv __P((BTREE *, EPG *, int));
static int __bt_seqset __P((BTREE *, EPG *, DBT *, int));
/*
* Sequential scan support.
*
* The tree can be scanned sequentially, starting from either end of the
* tree or from any specific key. A scan request before any scanning is
* done is initialized as starting from the least node.
*/
/*
* __bt_seq --
* Btree sequential scan interface.
*
* Parameters:
* dbp: pointer to access method
* key: key for positioning and return value
* data: data return value
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
int
__bt_seq(dbp, key, data, flags)
const DB *dbp;
DBT *key, *data;
u_int flags;
{
BTREE *t;
EPG e;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/*
* If scan unitialized as yet, or starting at a specific record, set
* the scan to a specific key. Both __bt_seqset and __bt_seqadv pin
* the page the cursor references if they're successful.
*/
switch (flags) {
case R_NEXT:
case R_PREV:
if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
status = __bt_seqadv(t, &e, flags);
break;
}
/* FALLTHROUGH */
case R_FIRST:
case R_LAST:
case R_CURSOR:
status = __bt_seqset(t, &e, key, flags);
break;
default:
errno = EINVAL;
return (RET_ERROR);
}
if (status == RET_SUCCESS) {
__bt_setcur(t, e.page->pgno, e.index);
status =
__bt_ret(t, &e, key, &t->bt_rkey, data, &t->bt_rdata, 0);
/*
* If the user is doing concurrent access, we copied the
* key/data, toss the page.
*/
if (F_ISSET(t, B_DB_LOCK))
mpool_put(t->bt_mp, e.page, 0);
else
t->bt_pinned = e.page;
}
return (status);
}
/*
* __bt_seqset --
* Set the sequential scan to a specific key.
*
* Parameters:
* t: tree
* ep: storage for returned key
* key: key for initial scan position
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV
*
* Side effects:
* Pins the page the cursor references.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
static int
__bt_seqset(t, ep, key, flags)
BTREE *t;
EPG *ep;
DBT *key;
int flags;
{
PAGE *h;
pgno_t pg;
int exact;
/*
* Find the first, last or specific key in the tree and point the
* cursor at it. The cursor may not be moved until a new key has
* been found.
*/
switch (flags) {
case R_CURSOR: /* Keyed scan. */
/*
* Find the first instance of the key or the smallest key
* which is greater than or equal to the specified key.
*/
if (key->data == NULL || key->size == 0) {
errno = EINVAL;
return (RET_ERROR);
}
return (__bt_first(t, key, ep, &exact));
case R_FIRST: /* First record. */
case R_NEXT:
/* Walk down the left-hand side of the tree. */
for (pg = P_ROOT;;) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
/* Check for an empty tree. */
if (NEXTINDEX(h) == 0) {
mpool_put(t->bt_mp, h, 0);
return (RET_SPECIAL);
}
if (h->flags & (P_BLEAF | P_RLEAF))
break;
pg = GETBINTERNAL(h, 0)->pgno;
mpool_put(t->bt_mp, h, 0);
}
ep->page = h;
ep->index = 0;
break;
case R_LAST: /* Last record. */
case R_PREV:
/* Walk down the right-hand side of the tree. */
for (pg = P_ROOT;;) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
/* Check for an empty tree. */
if (NEXTINDEX(h) == 0) {
mpool_put(t->bt_mp, h, 0);
return (RET_SPECIAL);
}
if (h->flags & (P_BLEAF | P_RLEAF))
break;
pg = GETBINTERNAL(h, NEXTINDEX(h) - 1)->pgno;
mpool_put(t->bt_mp, h, 0);
}
ep->page = h;
ep->index = NEXTINDEX(h) - 1;
break;
}
return (RET_SUCCESS);
}
/*
* __bt_seqadvance --
* Advance the sequential scan.
*
* Parameters:
* t: tree
* flags: R_NEXT, R_PREV
*
* Side effects:
* Pins the page the new key/data record is on.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
static int
__bt_seqadv(t, ep, flags)
BTREE *t;
EPG *ep;
int flags;
{
CURSOR *c;
PAGE *h;
indx_t index;
pgno_t pg;
int exact;
/*
* There are a couple of states that we can be in. The cursor has
* been initialized by the time we get here, but that's all we know.
*/
c = &t->bt_cursor;
/*
* The cursor was deleted where there weren't any duplicate records,
* so the key was saved. Find out where that key would go in the
* current tree. It doesn't matter if the returned key is an exact
* match or not -- if it's an exact match, the record was added after
* the delete so we can just return it. If not, as long as there's
* a record there, return it.
*/
if (F_ISSET(c, CURS_ACQUIRE))
return (__bt_first(t, &c->key, ep, &exact));
/* Get the page referenced by the cursor. */
if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
return (RET_ERROR);
/*
* Find the next/previous record in the tree and point the cursor at
* it. The cursor may not be moved until a new key has been found.
*/
switch (flags) {
case R_NEXT: /* Next record. */
/*
* The cursor was deleted in duplicate records, and moved
* forward to a record that has yet to be returned. Clear
* that flag, and return the record.
*/
if (F_ISSET(c, CURS_AFTER))
goto usecurrent;
index = c->pg.index;
if (++index == NEXTINDEX(h)) {
pg = h->nextpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
index = 0;
}
break;
case R_PREV: /* Previous record. */
/*
* The cursor was deleted in duplicate records, and moved
* backward to a record that has yet to be returned. Clear
* that flag, and return the record.
*/
if (F_ISSET(c, CURS_BEFORE)) {
usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
ep->page = h;
ep->index = c->pg.index;
return (RET_SUCCESS);
}
index = c->pg.index;
if (index == 0) {
pg = h->prevpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
index = NEXTINDEX(h) - 1;
} else
--index;
break;
}
ep->page = h;
ep->index = index;
return (RET_SUCCESS);
}
/*
* __bt_first --
* Find the first entry.
*
* Parameters:
* t: the tree
* key: the key
* erval: return EPG
* exactp: pointer to exact match flag
*
* Returns:
* The first entry in the tree greater than or equal to key,
* or RET_SPECIAL if no such key exists.
*/
static int
__bt_first(t, key, erval, exactp)
BTREE *t;
const DBT *key;
EPG *erval;
int *exactp;
{
PAGE *h;
EPG *ep, save;
pgno_t pg;
/*
* Find any matching record; __bt_search pins the page.
*
* If it's an exact match and duplicates are possible, walk backwards
* in the tree until we find the first one. Otherwise, make sure it's
* a valid key (__bt_search may return an index just past the end of a
* page) and return it.
*/
if ((ep = __bt_search(t, key, exactp)) == NULL)
return (RET_SPECIAL);
if (*exactp) {
if (F_ISSET(t, B_NODUPS)) {
*erval = *ep;
return (RET_SUCCESS);
}
/*
* Walk backwards, as long as the entry matches and there are
* keys left in the tree. Save a copy of each match in case
* we go too far.
*/
save = *ep;
h = ep->page;
do {
if (save.page->pgno != ep->page->pgno) {
mpool_put(t->bt_mp, save.page, 0);
save = *ep;
} else
save.index = ep->index;
/*
* Don't unpin the page the last (or original) match
* was on, but make sure it's unpinned if an error
* occurs.
*/
if (ep->index == 0) {
if (h->prevpg == P_INVALID)
break;
if (h->pgno != save.page->pgno)
mpool_put(t->bt_mp, h, 0);
if ((h = mpool_get(t->bt_mp,
h->prevpg, 0)) == NULL) {
if (h->pgno == save.page->pgno)
mpool_put(t->bt_mp,
save.page, 0);
return (RET_ERROR);
}
ep->page = h;
ep->index = NEXTINDEX(h);
}
--ep->index;
} while (__bt_cmp(t, key, ep) == 0);
/*
* Reach here with the last page that was looked at pinned,
* which may or may not be the same as the last (or original)
* match page. If it's not useful, release it.
*/
if (h->pgno != save.page->pgno)
mpool_put(t->bt_mp, h, 0);
*erval = save;
return (RET_SUCCESS);
}
/* If at the end of a page, find the next entry. */
if (ep->index == NEXTINDEX(ep->page)) {
h = ep->page;
pg = h->nextpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
ep->index = 0;
ep->page = h;
}
*erval = *ep;
return (RET_SUCCESS);
}
/*
* __bt_setcur --
* Set the cursor to an entry in the tree.
*
* Parameters:
* t: the tree
* pgno: page number
* index: page index
*/
void
__bt_setcur(t, pgno, index)
BTREE *t;
pgno_t pgno;
u_int index;
{
/* Lose any already deleted key. */
if (t->bt_cursor.key.data != NULL) {
free(t->bt_cursor.key.data);
t->bt_cursor.key.size = 0;
t->bt_cursor.key.data = NULL;
}
F_CLR(&t->bt_cursor, CURS_ACQUIRE | CURS_AFTER | CURS_BEFORE);
/* Update the cursor. */
t->bt_cursor.pg.pgno = pgno;
t->bt_cursor.pg.index = index;
F_SET(&t->bt_cursor, CURS_INIT);
}
+827
View File
@@ -0,0 +1,827 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_split.c 8.9 (Berkeley) 7/26/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
static int bt_broot __P((BTREE *, PAGE *, PAGE *, PAGE *));
static PAGE *bt_page
__P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
static int bt_preserve __P((BTREE *, pgno_t));
static PAGE *bt_psplit
__P((BTREE *, PAGE *, PAGE *, PAGE *, indx_t *, size_t));
static PAGE *bt_root
__P((BTREE *, PAGE *, PAGE **, PAGE **, indx_t *, size_t));
static int bt_rroot __P((BTREE *, PAGE *, PAGE *, PAGE *));
static recno_t rec_total __P((PAGE *));
#ifdef STATISTICS
u_long bt_rootsplit, bt_split, bt_sortsplit, bt_pfxsaved;
#endif
/*
* __BT_SPLIT -- Split the tree.
*
* Parameters:
* t: tree
* sp: page to split
* key: key to insert
* data: data to insert
* flags: BIGKEY/BIGDATA flags
* ilen: insert length
* skip: index to leave open
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__bt_split(t, sp, key, data, flags, ilen, argskip)
BTREE *t;
PAGE *sp;
const DBT *key, *data;
int flags;
size_t ilen;
u_int32_t argskip;
{
BINTERNAL *bi;
BLEAF *bl, *tbl;
DBT a, b;
EPGNO *parent;
PAGE *h, *l, *r, *lchild, *rchild;
indx_t nxtindex;
u_int16_t skip;
u_int32_t n, nbytes, nksize;
int parentsplit;
char *dest;
/*
* Split the page into two pages, l and r. The split routines return
* a pointer to the page into which the key should be inserted and with
* skip set to the offset which should be used. Additionally, l and r
* are pinned.
*/
skip = argskip;
h = sp->pgno == P_ROOT ?
bt_root(t, sp, &l, &r, &skip, ilen) :
bt_page(t, sp, &l, &r, &skip, ilen);
if (h == NULL)
return (RET_ERROR);
/*
* Insert the new key/data pair into the leaf page. (Key inserts
* always cause a leaf page to split first.)
*/
h->linp[skip] = h->upper -= ilen;
dest = (char *)h + h->upper;
if (F_ISSET(t, R_RECNO))
WR_RLEAF(dest, data, flags)
else
WR_BLEAF(dest, key, data, flags)
/* If the root page was split, make it look right. */
if (sp->pgno == P_ROOT &&
(F_ISSET(t, R_RECNO) ?
bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
goto err2;
/*
* Now we walk the parent page stack -- a LIFO stack of the pages that
* were traversed when we searched for the page that split. Each stack
* entry is a page number and a page index offset. The offset is for
* the page traversed on the search. We've just split a page, so we
* have to insert a new key into the parent page.
*
* If the insert into the parent page causes it to split, may have to
* continue splitting all the way up the tree. We stop if the root
* splits or the page inserted into didn't have to split to hold the
* new key. Some algorithms replace the key for the old page as well
* as the new page. We don't, as there's no reason to believe that the
* first key on the old page is any better than the key we have, and,
* in the case of a key being placed at index 0 causing the split, the
* key is unavailable.
*
* There are a maximum of 5 pages pinned at any time. We keep the left
* and right pages pinned while working on the parent. The 5 are the
* two children, left parent and right parent (when the parent splits)
* and the root page or the overflow key page when calling bt_preserve.
* This code must make sure that all pins are released other than the
* root page or overflow page which is unlocked elsewhere.
*/
while ((parent = BT_POP(t)) != NULL) {
lchild = l;
rchild = r;
/* Get the parent page. */
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
goto err2;
/*
* The new key goes ONE AFTER the index, because the split
* was to the right.
*/
skip = parent->index + 1;
/*
* Calculate the space needed on the parent page.
*
* Prefix trees: space hack when inserting into BINTERNAL
* pages. Retain only what's needed to distinguish between
* the new entry and the LAST entry on the page to its left.
* If the keys compare equal, retain the entire key. Note,
* we don't touch overflow keys, and the entire key must be
* retained for the next-to-left most key on the leftmost
* page of each level, or the search will fail. Applicable
* ONLY to internal pages that have leaf pages as children.
* Further reduction of the key between pairs of internal
* pages loses too much information.
*/
switch (rchild->flags & P_TYPE) {
case P_BINTERNAL:
bi = GETBINTERNAL(rchild, 0);
nbytes = NBINTERNAL(bi->ksize);
break;
case P_BLEAF:
bl = GETBLEAF(rchild, 0);
nbytes = NBINTERNAL(bl->ksize);
if (t->bt_pfx && !(bl->flags & P_BIGKEY) &&
(h->prevpg != P_INVALID || skip > 1)) {
tbl = GETBLEAF(lchild, NEXTINDEX(lchild) - 1);
a.size = tbl->ksize;
a.data = tbl->bytes;
b.size = bl->ksize;
b.data = bl->bytes;
nksize = t->bt_pfx(&a, &b);
n = NBINTERNAL(nksize);
if (n < nbytes) {
#ifdef STATISTICS
bt_pfxsaved += nbytes - n;
#endif
nbytes = n;
} else
nksize = 0;
} else
nksize = 0;
break;
case P_RINTERNAL:
case P_RLEAF:
nbytes = NRINTERNAL;
break;
default:
abort();
}
/* Split the parent page if necessary or shift the indices. */
if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
sp = h;
h = h->pgno == P_ROOT ?
bt_root(t, h, &l, &r, &skip, nbytes) :
bt_page(t, h, &l, &r, &skip, nbytes);
if (h == NULL)
goto err1;
parentsplit = 1;
} else {
if (skip < (nxtindex = NEXTINDEX(h)))
memmove(h->linp + skip + 1, h->linp + skip,
(nxtindex - skip) * sizeof(indx_t));
h->lower += sizeof(indx_t);
parentsplit = 0;
}
/* Insert the key into the parent page. */
switch (rchild->flags & P_TYPE) {
case P_BINTERNAL:
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
memmove(dest, bi, nbytes);
((BINTERNAL *)dest)->pgno = rchild->pgno;
break;
case P_BLEAF:
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
WR_BINTERNAL(dest, nksize ? nksize : bl->ksize,
rchild->pgno, bl->flags & P_BIGKEY);
memmove(dest, bl->bytes, nksize ? nksize : bl->ksize);
if (bl->flags & P_BIGKEY &&
bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
goto err1;
break;
case P_RINTERNAL:
/*
* Update the left page count. If split
* added at index 0, fix the correct page.
*/
if (skip > 0)
dest = (char *)h + h->linp[skip - 1];
else
dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
((RINTERNAL *)dest)->nrecs = rec_total(lchild);
((RINTERNAL *)dest)->pgno = lchild->pgno;
/* Update the right page count. */
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
((RINTERNAL *)dest)->nrecs = rec_total(rchild);
((RINTERNAL *)dest)->pgno = rchild->pgno;
break;
case P_RLEAF:
/*
* Update the left page count. If split
* added at index 0, fix the correct page.
*/
if (skip > 0)
dest = (char *)h + h->linp[skip - 1];
else
dest = (char *)l + l->linp[NEXTINDEX(l) - 1];
((RINTERNAL *)dest)->nrecs = NEXTINDEX(lchild);
((RINTERNAL *)dest)->pgno = lchild->pgno;
/* Update the right page count. */
h->linp[skip] = h->upper -= nbytes;
dest = (char *)h + h->linp[skip];
((RINTERNAL *)dest)->nrecs = NEXTINDEX(rchild);
((RINTERNAL *)dest)->pgno = rchild->pgno;
break;
default:
abort();
}
/* Unpin the held pages. */
if (!parentsplit) {
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
break;
}
/* If the root page was split, make it look right. */
if (sp->pgno == P_ROOT &&
(F_ISSET(t, R_RECNO) ?
bt_rroot(t, sp, l, r) : bt_broot(t, sp, l, r)) == RET_ERROR)
goto err1;
mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
}
/* Unpin the held pages. */
mpool_put(t->bt_mp, l, MPOOL_DIRTY);
mpool_put(t->bt_mp, r, MPOOL_DIRTY);
/* Clear any pages left on the stack. */
return (RET_SUCCESS);
/*
* If something fails in the above loop we were already walking back
* up the tree and the tree is now inconsistent. Nothing much we can
* do about it but release any memory we're holding.
*/
err1: mpool_put(t->bt_mp, lchild, MPOOL_DIRTY);
mpool_put(t->bt_mp, rchild, MPOOL_DIRTY);
err2: mpool_put(t->bt_mp, l, 0);
mpool_put(t->bt_mp, r, 0);
__dbpanic(t->bt_dbp);
return (RET_ERROR);
}
/*
* BT_PAGE -- Split a non-root page of a btree.
*
* Parameters:
* t: tree
* h: root page
* lp: pointer to left page pointer
* rp: pointer to right page pointer
* skip: pointer to index to leave open
* ilen: insert length
*
* Returns:
* Pointer to page in which to insert or NULL on error.
*/
static PAGE *
bt_page(t, h, lp, rp, skip, ilen)
BTREE *t;
PAGE *h, **lp, **rp;
indx_t *skip;
size_t ilen;
{
PAGE *l, *r, *tp;
pgno_t npg;
#ifdef STATISTICS
++bt_split;
#endif
/* Put the new right page for the split into place. */
if ((r = __bt_new(t, &npg)) == NULL)
return (NULL);
r->pgno = npg;
r->lower = BTDATAOFF;
r->upper = t->bt_psize;
r->nextpg = h->nextpg;
r->prevpg = h->pgno;
r->flags = h->flags & P_TYPE;
/*
* If we're splitting the last page on a level because we're appending
* a key to it (skip is NEXTINDEX()), it's likely that the data is
* sorted. Adding an empty page on the side of the level is less work
* and can push the fill factor much higher than normal. If we're
* wrong it's no big deal, we'll just do the split the right way next
* time. It may look like it's equally easy to do a similar hack for
* reverse sorted data, that is, split the tree left, but it's not.
* Don't even try.
*/
if (h->nextpg == P_INVALID && *skip == NEXTINDEX(h)) {
#ifdef STATISTICS
++bt_sortsplit;
#endif
h->nextpg = r->pgno;
r->lower = BTDATAOFF + sizeof(indx_t);
*skip = 0;
*lp = h;
*rp = r;
return (r);
}
/* Put the new left page for the split into place. */
if ((l = (PAGE *)malloc(t->bt_psize)) == NULL) {
mpool_put(t->bt_mp, r, 0);
return (NULL);
}
#ifdef PURIFY
memset(l, 0xff, t->bt_psize);
#endif
l->pgno = h->pgno;
l->nextpg = r->pgno;
l->prevpg = h->prevpg;
l->lower = BTDATAOFF;
l->upper = t->bt_psize;
l->flags = h->flags & P_TYPE;
/* Fix up the previous pointer of the page after the split page. */
if (h->nextpg != P_INVALID) {
if ((tp = mpool_get(t->bt_mp, h->nextpg, 0)) == NULL) {
free(l);
/* XXX mpool_free(t->bt_mp, r->pgno); */
return (NULL);
}
tp->prevpg = r->pgno;
mpool_put(t->bt_mp, tp, MPOOL_DIRTY);
}
/*
* Split right. The key/data pairs aren't sorted in the btree page so
* it's simpler to copy the data from the split page onto two new pages
* instead of copying half the data to the right page and compacting
* the left page in place. Since the left page can't change, we have
* to swap the original and the allocated left page after the split.
*/
tp = bt_psplit(t, h, l, r, skip, ilen);
/* Move the new left page onto the old left page. */
memmove(h, l, t->bt_psize);
if (tp == l)
tp = h;
free(l);
*lp = h;
*rp = r;
return (tp);
}
/*
* BT_ROOT -- Split the root page of a btree.
*
* Parameters:
* t: tree
* h: root page
* lp: pointer to left page pointer
* rp: pointer to right page pointer
* skip: pointer to index to leave open
* ilen: insert length
*
* Returns:
* Pointer to page in which to insert or NULL on error.
*/
static PAGE *
bt_root(t, h, lp, rp, skip, ilen)
BTREE *t;
PAGE *h, **lp, **rp;
indx_t *skip;
size_t ilen;
{
PAGE *l, *r, *tp;
pgno_t lnpg, rnpg;
#ifdef STATISTICS
++bt_split;
++bt_rootsplit;
#endif
/* Put the new left and right pages for the split into place. */
if ((l = __bt_new(t, &lnpg)) == NULL ||
(r = __bt_new(t, &rnpg)) == NULL)
return (NULL);
l->pgno = lnpg;
r->pgno = rnpg;
l->nextpg = r->pgno;
r->prevpg = l->pgno;
l->prevpg = r->nextpg = P_INVALID;
l->lower = r->lower = BTDATAOFF;
l->upper = r->upper = t->bt_psize;
l->flags = r->flags = h->flags & P_TYPE;
/* Split the root page. */
tp = bt_psplit(t, h, l, r, skip, ilen);
*lp = l;
*rp = r;
return (tp);
}
/*
* BT_RROOT -- Fix up the recno root page after it has been split.
*
* Parameters:
* t: tree
* h: root page
* l: left page
* r: right page
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
bt_rroot(t, h, l, r)
BTREE *t;
PAGE *h, *l, *r;
{
char *dest;
/* Insert the left and right keys, set the header information. */
h->linp[0] = h->upper = t->bt_psize - NRINTERNAL;
dest = (char *)h + h->upper;
WR_RINTERNAL(dest,
l->flags & P_RLEAF ? NEXTINDEX(l) : rec_total(l), l->pgno);
h->linp[1] = h->upper -= NRINTERNAL;
dest = (char *)h + h->upper;
WR_RINTERNAL(dest,
r->flags & P_RLEAF ? NEXTINDEX(r) : rec_total(r), r->pgno);
h->lower = BTDATAOFF + 2 * sizeof(indx_t);
/* Unpin the root page, set to recno internal page. */
h->flags &= ~P_TYPE;
h->flags |= P_RINTERNAL;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
/*
* BT_BROOT -- Fix up the btree root page after it has been split.
*
* Parameters:
* t: tree
* h: root page
* l: left page
* r: right page
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
static int
bt_broot(t, h, l, r)
BTREE *t;
PAGE *h, *l, *r;
{
BINTERNAL *bi;
BLEAF *bl;
u_int32_t nbytes;
char *dest;
/*
* If the root page was a leaf page, change it into an internal page.
* We copy the key we split on (but not the key's data, in the case of
* a leaf page) to the new root page.
*
* The btree comparison code guarantees that the left-most key on any
* level of the tree is never used, so it doesn't need to be filled in.
*/
nbytes = NBINTERNAL(0);
h->linp[0] = h->upper = t->bt_psize - nbytes;
dest = (char *)h + h->upper;
WR_BINTERNAL(dest, 0, l->pgno, 0);
switch (h->flags & P_TYPE) {
case P_BLEAF:
bl = GETBLEAF(r, 0);
nbytes = NBINTERNAL(bl->ksize);
h->linp[1] = h->upper -= nbytes;
dest = (char *)h + h->upper;
WR_BINTERNAL(dest, bl->ksize, r->pgno, 0);
memmove(dest, bl->bytes, bl->ksize);
/*
* If the key is on an overflow page, mark the overflow chain
* so it isn't deleted when the leaf copy of the key is deleted.
*/
if (bl->flags & P_BIGKEY &&
bt_preserve(t, *(pgno_t *)bl->bytes) == RET_ERROR)
return (RET_ERROR);
break;
case P_BINTERNAL:
bi = GETBINTERNAL(r, 0);
nbytes = NBINTERNAL(bi->ksize);
h->linp[1] = h->upper -= nbytes;
dest = (char *)h + h->upper;
memmove(dest, bi, nbytes);
((BINTERNAL *)dest)->pgno = r->pgno;
break;
default:
abort();
}
/* There are two keys on the page. */
h->lower = BTDATAOFF + 2 * sizeof(indx_t);
/* Unpin the root page, set to btree internal page. */
h->flags &= ~P_TYPE;
h->flags |= P_BINTERNAL;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
/*
* BT_PSPLIT -- Do the real work of splitting the page.
*
* Parameters:
* t: tree
* h: page to be split
* l: page to put lower half of data
* r: page to put upper half of data
* pskip: pointer to index to leave open
* ilen: insert length
*
* Returns:
* Pointer to page in which to insert.
*/
static PAGE *
bt_psplit(t, h, l, r, pskip, ilen)
BTREE *t;
PAGE *h, *l, *r;
indx_t *pskip;
size_t ilen;
{
BINTERNAL *bi;
BLEAF *bl;
CURSOR *c;
RLEAF *rl;
PAGE *rval;
void *src;
indx_t full, half, nxt, off, skip, top, used;
u_int32_t nbytes;
int bigkeycnt, isbigkey;
/*
* Split the data to the left and right pages. Leave the skip index
* open. Additionally, make some effort not to split on an overflow
* key. This makes internal page processing faster and can save
* space as overflow keys used by internal pages are never deleted.
*/
bigkeycnt = 0;
skip = *pskip;
full = t->bt_psize - BTDATAOFF;
half = full / 2;
used = 0;
for (nxt = off = 0, top = NEXTINDEX(h); nxt < top; ++off) {
if (skip == off) {
nbytes = ilen;
isbigkey = 0; /* XXX: not really known. */
} else
switch (h->flags & P_TYPE) {
case P_BINTERNAL:
src = bi = GETBINTERNAL(h, nxt);
nbytes = NBINTERNAL(bi->ksize);
isbigkey = bi->flags & P_BIGKEY;
break;
case P_BLEAF:
src = bl = GETBLEAF(h, nxt);
nbytes = NBLEAF(bl);
isbigkey = bl->flags & P_BIGKEY;
break;
case P_RINTERNAL:
src = GETRINTERNAL(h, nxt);
nbytes = NRINTERNAL;
isbigkey = 0;
break;
case P_RLEAF:
src = rl = GETRLEAF(h, nxt);
nbytes = NRLEAF(rl);
isbigkey = 0;
break;
default:
abort();
}
/*
* If the key/data pairs are substantial fractions of the max
* possible size for the page, it's possible to get situations
* where we decide to try and copy too much onto the left page.
* Make sure that doesn't happen.
*/
if (skip <= off && used + nbytes >= full) {
--off;
break;
}
/* Copy the key/data pair, if not the skipped index. */
if (skip != off) {
++nxt;
l->linp[off] = l->upper -= nbytes;
memmove((char *)l + l->upper, src, nbytes);
}
used += nbytes;
if (used >= half) {
if (!isbigkey || bigkeycnt == 3)
break;
else
++bigkeycnt;
}
}
/*
* Off is the last offset that's valid for the left page.
* Nxt is the first offset to be placed on the right page.
*/
l->lower += (off + 1) * sizeof(indx_t);
/*
* If splitting the page that the cursor was on, the cursor has to be
* adjusted to point to the same record as before the split. If the
* cursor is at or past the skipped slot, the cursor is incremented by
* one. If the cursor is on the right page, it is decremented by the
* number of records split to the left page.
*/
c = &t->bt_cursor;
if (F_ISSET(c, CURS_INIT) && c->pg.pgno == h->pgno) {
if (c->pg.index >= skip)
++c->pg.index;
if (c->pg.index < nxt) /* Left page. */
c->pg.pgno = l->pgno;
else { /* Right page. */
c->pg.pgno = r->pgno;
c->pg.index -= nxt;
}
}
/*
* If the skipped index was on the left page, just return that page.
* Otherwise, adjust the skip index to reflect the new position on
* the right page.
*/
if (skip <= off) {
skip = 0;
rval = l;
} else {
rval = r;
*pskip -= nxt;
}
for (off = 0; nxt < top; ++off) {
if (skip == nxt) {
++off;
skip = 0;
}
switch (h->flags & P_TYPE) {
case P_BINTERNAL:
src = bi = GETBINTERNAL(h, nxt);
nbytes = NBINTERNAL(bi->ksize);
break;
case P_BLEAF:
src = bl = GETBLEAF(h, nxt);
nbytes = NBLEAF(bl);
break;
case P_RINTERNAL:
src = GETRINTERNAL(h, nxt);
nbytes = NRINTERNAL;
break;
case P_RLEAF:
src = rl = GETRLEAF(h, nxt);
nbytes = NRLEAF(rl);
break;
default:
abort();
}
++nxt;
r->linp[off] = r->upper -= nbytes;
memmove((char *)r + r->upper, src, nbytes);
}
r->lower += off * sizeof(indx_t);
/* If the key is being appended to the page, adjust the index. */
if (skip == top)
r->lower += sizeof(indx_t);
return (rval);
}
/*
* BT_PRESERVE -- Mark a chain of pages as used by an internal node.
*
* Chains of indirect blocks pointed to by leaf nodes get reclaimed when the
* record that references them gets deleted. Chains pointed to by internal
* pages never get deleted. This routine marks a chain as pointed to by an
* internal page.
*
* Parameters:
* t: tree
* pg: page number of first page in the chain.
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
static int
bt_preserve(t, pg)
BTREE *t;
pgno_t pg;
{
PAGE *h;
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
h->flags |= P_PRESERVE;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
/*
* REC_TOTAL -- Return the number of recno entries below a page.
*
* Parameters:
* h: page
*
* Returns:
* The number of recno entries below a page.
*
* XXX
* These values could be set by the bt_psplit routine. The problem is that the
* entry has to be popped off of the stack etc. or the values have to be passed
* all the way back to bt_split/bt_rroot and it's not very clean.
*/
static recno_t
rec_total(h)
PAGE *h;
{
recno_t recs;
indx_t nxt, top;
for (recs = 0, nxt = 0, top = NEXTINDEX(h); nxt < top; ++nxt)
recs += GETRINTERNAL(h, nxt)->nrecs;
return (recs);
}
+260
View File
@@ -0,0 +1,260 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)bt_utils.c 8.8 (Berkeley) 7/20/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "btree.h"
/*
* __bt_ret --
* Build return key/data pair.
*
* Parameters:
* t: tree
* e: key/data pair to be returned
* key: user's key structure (NULL if not to be filled in)
* rkey: memory area to hold key
* data: user's data structure (NULL if not to be filled in)
* rdata: memory area to hold data
* copy: always copy the key/data item
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__bt_ret(t, e, key, rkey, data, rdata, copy)
BTREE *t;
EPG *e;
DBT *key, *rkey, *data, *rdata;
int copy;
{
BLEAF *bl;
void *p;
bl = GETBLEAF(e->page, e->index);
/*
* We must copy big keys/data to make them contigous. Otherwise,
* leave the page pinned and don't copy unless the user specified
* concurrent access.
*/
if (key == NULL)
goto dataonly;
if (bl->flags & P_BIGKEY) {
if (__ovfl_get(t, bl->bytes,
&key->size, &rkey->data, &rkey->size))
return (RET_ERROR);
key->data = rkey->data;
} else if (copy || F_ISSET(t, B_DB_LOCK)) {
if (bl->ksize > rkey->size) {
p = (void *)(rkey->data == NULL ?
malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
if (p == NULL)
return (RET_ERROR);
rkey->data = p;
rkey->size = bl->ksize;
}
memmove(rkey->data, bl->bytes, bl->ksize);
key->size = bl->ksize;
key->data = rkey->data;
} else {
key->size = bl->ksize;
key->data = bl->bytes;
}
dataonly:
if (data == NULL)
return (RET_SUCCESS);
if (bl->flags & P_BIGDATA) {
if (__ovfl_get(t, bl->bytes + bl->ksize,
&data->size, &rdata->data, &rdata->size))
return (RET_ERROR);
data->data = rdata->data;
} else if (copy || F_ISSET(t, B_DB_LOCK)) {
/* Use +1 in case the first record retrieved is 0 length. */
if (bl->dsize + 1 > rdata->size) {
p = (void *)(rdata->data == NULL ?
malloc(bl->dsize + 1) :
realloc(rdata->data, bl->dsize + 1));
if (p == NULL)
return (RET_ERROR);
rdata->data = p;
rdata->size = bl->dsize + 1;
}
memmove(rdata->data, bl->bytes + bl->ksize, bl->dsize);
data->size = bl->dsize;
data->data = rdata->data;
} else {
data->size = bl->dsize;
data->data = bl->bytes + bl->ksize;
}
return (RET_SUCCESS);
}
/*
* __BT_CMP -- Compare a key to a given record.
*
* Parameters:
* t: tree
* k1: DBT pointer of first arg to comparison
* e: pointer to EPG for comparison
*
* Returns:
* < 0 if k1 is < record
* = 0 if k1 is = record
* > 0 if k1 is > record
*/
int
__bt_cmp(t, k1, e)
BTREE *t;
const DBT *k1;
EPG *e;
{
BINTERNAL *bi;
BLEAF *bl;
DBT k2;
PAGE *h;
void *bigkey;
/*
* The left-most key on internal pages, at any level of the tree, is
* guaranteed by the following code to be less than any user key.
* This saves us from having to update the leftmost key on an internal
* page when the user inserts a new key in the tree smaller than
* anything we've yet seen.
*/
h = e->page;
if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & P_BLEAF))
return (1);
bigkey = NULL;
if (h->flags & P_BLEAF) {
bl = GETBLEAF(h, e->index);
if (bl->flags & P_BIGKEY)
bigkey = bl->bytes;
else {
k2.data = bl->bytes;
k2.size = bl->ksize;
}
} else {
bi = GETBINTERNAL(h, e->index);
if (bi->flags & P_BIGKEY)
bigkey = bi->bytes;
else {
k2.data = bi->bytes;
k2.size = bi->ksize;
}
}
if (bigkey) {
if (__ovfl_get(t, bigkey,
&k2.size, &t->bt_rdata.data, &t->bt_rdata.size))
return (RET_ERROR);
k2.data = t->bt_rdata.data;
}
return ((*t->bt_cmp)(k1, &k2));
}
/*
* __BT_DEFCMP -- Default comparison routine.
*
* Parameters:
* a: DBT #1
* b: DBT #2
*
* Returns:
* < 0 if a is < b
* = 0 if a is = b
* > 0 if a is > b
*/
int
__bt_defcmp(a, b)
const DBT *a, *b;
{
register size_t len;
register u_char *p1, *p2;
/*
* XXX
* If a size_t doesn't fit in an int, this routine can lose.
* What we need is a integral type which is guaranteed to be
* larger than a size_t, and there is no such thing.
*/
len = MIN(a->size, b->size);
for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2)
if (*p1 != *p2)
return ((int)*p1 - (int)*p2);
return ((int)a->size - (int)b->size);
}
/*
* __BT_DEFPFX -- Default prefix routine.
*
* Parameters:
* a: DBT #1
* b: DBT #2
*
* Returns:
* Number of bytes needed to distinguish b from a.
*/
size_t
__bt_defpfx(a, b)
const DBT *a, *b;
{
register u_char *p1, *p2;
register size_t cnt, len;
cnt = 1;
len = MIN(a->size, b->size);
for (p1 = a->data, p2 = b->data; len--; ++p1, ++p2, ++cnt)
if (*p1 != *p2)
return (cnt);
/* a->size must be <= b->size, or they wouldn't be in this order. */
return (a->size < b->size ? a->size + 1 : a->size);
}
+383
View File
@@ -0,0 +1,383 @@
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)btree.h 8.11 (Berkeley) 8/17/94
*/
/* Macros to set/clear/test flags. */
#define F_SET(p, f) (p)->flags |= (f)
#define F_CLR(p, f) (p)->flags &= ~(f)
#define F_ISSET(p, f) ((p)->flags & (f))
#include <mpool.h>
#define DEFMINKEYPAGE (2) /* Minimum keys per page */
#define MINCACHE (5) /* Minimum cached pages */
#define MINPSIZE (512) /* Minimum page size */
/*
* Page 0 of a btree file contains a copy of the meta-data. This page is also
* used as an out-of-band page, i.e. page pointers that point to nowhere point
* to page 0. Page 1 is the root of the btree.
*/
#define P_INVALID 0 /* Invalid tree page number. */
#define P_META 0 /* Tree metadata page number. */
#define P_ROOT 1 /* Tree root page number. */
/*
* There are five page layouts in the btree: btree internal pages (BINTERNAL),
* btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
* (RLEAF) and overflow pages. All five page types have a page header (PAGE).
* This implementation requires that values within structures NOT be padded.
* (ANSI C permits random padding.) If your compiler pads randomly you'll have
* to do some work to get this package to run.
*/
typedef struct _page {
pgno_t pgno; /* this page's page number */
pgno_t prevpg; /* left sibling */
pgno_t nextpg; /* right sibling */
#define P_BINTERNAL 0x01 /* btree internal page */
#define P_BLEAF 0x02 /* leaf page */
#define P_OVERFLOW 0x04 /* overflow page */
#define P_RINTERNAL 0x08 /* recno internal page */
#define P_RLEAF 0x10 /* leaf page */
#define P_TYPE 0x1f /* type mask */
#define P_PRESERVE 0x20 /* never delete this chain of pages */
u_int32_t flags;
indx_t lower; /* lower bound of free space on page */
indx_t upper; /* upper bound of free space on page */
indx_t linp[1]; /* indx_t-aligned VAR. LENGTH DATA */
} PAGE;
/* First and next index. */
#define BTDATAOFF \
(sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t))
#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
/*
* For pages other than overflow pages, there is an array of offsets into the
* rest of the page immediately following the page header. Each offset is to
* an item which is unique to the type of page. The h_lower offset is just
* past the last filled-in index. The h_upper offset is the first item on the
* page. Offsets are from the beginning of the page.
*
* If an item is too big to store on a single page, a flag is set and the item
* is a { page, size } pair such that the page is the first page of an overflow
* chain with size bytes of item. Overflow pages are simply bytes without any
* external structure.
*
* The page number and size fields in the items are pgno_t-aligned so they can
* be manipulated without copying. (This presumes that 32 bit items can be
* manipulated on this system.)
*/
#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1))
#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t))
/*
* For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
* pairs, such that the key compares less than or equal to all of the records
* on that page. For a tree without duplicate keys, an internal page with two
* consecutive keys, a and b, will have all records greater than or equal to a
* and less than b stored on the page associated with a. Duplicate keys are
* somewhat special and can cause duplicate internal and leaf page records and
* some minor modifications of the above rule.
*/
typedef struct _binternal {
u_int32_t ksize; /* key size */
pgno_t pgno; /* page number stored on */
#define P_BIGDATA 0x01 /* overflow data */
#define P_BIGKEY 0x02 /* overflow key */
u_char flags;
char bytes[1]; /* data */
} BINTERNAL;
/* Get the page's BINTERNAL structure at index indx. */
#define GETBINTERNAL(pg, indx) \
((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NBINTERNAL(len) \
LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
/* Copy a BINTERNAL entry to the page. */
#define WR_BINTERNAL(p, size, pgno, flags) { \
*(u_int32_t *)p = size; \
p += sizeof(u_int32_t); \
*(pgno_t *)p = pgno; \
p += sizeof(pgno_t); \
*(u_char *)p = flags; \
p += sizeof(u_char); \
}
/*
* For the recno internal pages, the item is a page number with the number of
* keys found on that page and below.
*/
typedef struct _rinternal {
recno_t nrecs; /* number of records */
pgno_t pgno; /* page number stored below */
} RINTERNAL;
/* Get the page's RINTERNAL structure at index indx. */
#define GETRINTERNAL(pg, indx) \
((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NRINTERNAL \
LALIGN(sizeof(recno_t) + sizeof(pgno_t))
/* Copy a RINTERAL entry to the page. */
#define WR_RINTERNAL(p, nrecs, pgno) { \
*(recno_t *)p = nrecs; \
p += sizeof(recno_t); \
*(pgno_t *)p = pgno; \
}
/* For the btree leaf pages, the item is a key and data pair. */
typedef struct _bleaf {
u_int32_t ksize; /* size of key */
u_int32_t dsize; /* size of data */
u_char flags; /* P_BIGDATA, P_BIGKEY */
char bytes[1]; /* data */
} BLEAF;
/* Get the page's BLEAF structure at index indx. */
#define GETBLEAF(pg, indx) \
((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
/* Get the number of bytes in the user's key/data pair. */
#define NBLEAFDBT(ksize, dsize) \
LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \
(ksize) + (dsize))
/* Copy a BLEAF entry to the page. */
#define WR_BLEAF(p, key, data, flags) { \
*(u_int32_t *)p = key->size; \
p += sizeof(u_int32_t); \
*(u_int32_t *)p = data->size; \
p += sizeof(u_int32_t); \
*(u_char *)p = flags; \
p += sizeof(u_char); \
memmove(p, key->data, key->size); \
p += key->size; \
memmove(p, data->data, data->size); \
}
/* For the recno leaf pages, the item is a data entry. */
typedef struct _rleaf {
u_int32_t dsize; /* size of data */
u_char flags; /* P_BIGDATA */
char bytes[1];
} RLEAF;
/* Get the page's RLEAF structure at index indx. */
#define GETRLEAF(pg, indx) \
((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
/* Get the number of bytes in the entry. */
#define NRLEAF(p) NRLEAFDBT((p)->dsize)
/* Get the number of bytes from the user's data. */
#define NRLEAFDBT(dsize) \
LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize))
/* Copy a RLEAF entry to the page. */
#define WR_RLEAF(p, data, flags) { \
*(u_int32_t *)p = data->size; \
p += sizeof(u_int32_t); \
*(u_char *)p = flags; \
p += sizeof(u_char); \
memmove(p, data->data, data->size); \
}
/*
* A record in the tree is either a pointer to a page and an index in the page
* or a page number and an index. These structures are used as a cursor, stack
* entry and search returns as well as to pass records to other routines.
*
* One comment about searches. Internal page searches must find the largest
* record less than key in the tree so that descents work. Leaf page searches
* must find the smallest record greater than key so that the returned index
* is the record's correct position for insertion.
*/
typedef struct _epgno {
pgno_t pgno; /* the page number */
indx_t index; /* the index on the page */
} EPGNO;
typedef struct _epg {
PAGE *page; /* the (pinned) page */
indx_t index; /* the index on the page */
} EPG;
/*
* About cursors. The cursor (and the page that contained the key/data pair
* that it referenced) can be deleted, which makes things a bit tricky. If
* there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set
* or there simply aren't any duplicates of the key) we copy the key that it
* referenced when it's deleted, and reacquire a new cursor key if the cursor
* is used again. If there are duplicates keys, we move to the next/previous
* key, and set a flag so that we know what happened. NOTE: if duplicate (to
* the cursor) keys are added to the tree during this process, it is undefined
* if they will be returned or not in a cursor scan.
*
* The flags determine the possible states of the cursor:
*
* CURS_INIT The cursor references *something*.
* CURS_ACQUIRE The cursor was deleted, and a key has been saved so that
* we can reacquire the right position in the tree.
* CURS_AFTER, CURS_BEFORE
* The cursor was deleted, and now references a key/data pair
* that has not yet been returned, either before or after the
* deleted key/data pair.
* XXX
* This structure is broken out so that we can eventually offer multiple
* cursors as part of the DB interface.
*/
typedef struct _cursor {
EPGNO pg; /* B: Saved tree reference. */
DBT key; /* B: Saved key, or key.data == NULL. */
recno_t rcursor; /* R: recno cursor (1-based) */
#define CURS_ACQUIRE 0x01 /* B: Cursor needs to be reacquired. */
#define CURS_AFTER 0x02 /* B: Unreturned cursor after key. */
#define CURS_BEFORE 0x04 /* B: Unreturned cursor before key. */
#define CURS_INIT 0x08 /* RB: Cursor initialized. */
u_int8_t flags;
} CURSOR;
/*
* The metadata of the tree. The nrecs field is used only by the RECNO code.
* This is because the btree doesn't really need it and it requires that every
* put or delete call modify the metadata.
*/
typedef struct _btmeta {
u_int32_t magic; /* magic number */
u_int32_t version; /* version */
u_int32_t psize; /* page size */
u_int32_t free; /* page number of first free page */
u_int32_t nrecs; /* R: number of records */
#define SAVEMETA (B_NODUPS | R_RECNO)
u_int32_t flags; /* bt_flags & SAVEMETA */
} BTMETA;
/* The in-memory btree/recno data structure. */
typedef struct _btree {
MPOOL *bt_mp; /* memory pool cookie */
DB *bt_dbp; /* pointer to enclosing DB */
EPG bt_cur; /* current (pinned) page */
PAGE *bt_pinned; /* page pinned across calls */
CURSOR bt_cursor; /* cursor */
#define BT_PUSH(t, p, i) { \
t->bt_sp->pgno = p; \
t->bt_sp->index = i; \
++t->bt_sp; \
}
#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp)
#define BT_CLR(t) (t->bt_sp = t->bt_stack)
EPGNO bt_stack[50]; /* stack of parent pages */
EPGNO *bt_sp; /* current stack pointer */
DBT bt_rkey; /* returned key */
DBT bt_rdata; /* returned data */
int bt_fd; /* tree file descriptor */
pgno_t bt_free; /* next free page */
u_int32_t bt_psize; /* page size */
indx_t bt_ovflsize; /* cut-off for key/data overflow */
int bt_lorder; /* byte order */
/* sorted order */
enum { NOT, BACK, FORWARD } bt_order;
EPGNO bt_last; /* last insert */
/* B: key comparison function */
int (*bt_cmp) __P((const DBT *, const DBT *));
/* B: prefix comparison function */
size_t (*bt_pfx) __P((const DBT *, const DBT *));
/* R: recno input function */
int (*bt_irec) __P((struct _btree *, recno_t));
FILE *bt_rfp; /* R: record FILE pointer */
int bt_rfd; /* R: record file descriptor */
caddr_t bt_cmap; /* R: current point in mapped space */
caddr_t bt_smap; /* R: start of mapped space */
caddr_t bt_emap; /* R: end of mapped space */
size_t bt_msize; /* R: size of mapped region. */
recno_t bt_nrecs; /* R: number of records */
size_t bt_reclen; /* R: fixed record length */
u_char bt_bval; /* R: delimiting byte/pad character */
/*
* NB:
* B_NODUPS and R_RECNO are stored on disk, and may not be changed.
*/
#define B_INMEM 0x00001 /* in-memory tree */
#define B_METADIRTY 0x00002 /* need to write metadata */
#define B_MODIFIED 0x00004 /* tree modified */
#define B_NEEDSWAP 0x00008 /* if byte order requires swapping */
#define B_RDONLY 0x00010 /* read-only tree */
#define B_NODUPS 0x00020 /* no duplicate keys permitted */
#define R_RECNO 0x00080 /* record oriented tree */
#define R_CLOSEFP 0x00040 /* opened a file pointer */
#define R_EOF 0x00100 /* end of input file reached. */
#define R_FIXLEN 0x00200 /* fixed length records */
#define R_MEMMAPPED 0x00400 /* memory mapped file. */
#define R_INMEM 0x00800 /* in-memory file */
#define R_MODIFIED 0x01000 /* modified file */
#define R_RDONLY 0x02000 /* read-only file */
#define B_DB_LOCK 0x04000 /* DB_LOCK specified. */
#define B_DB_SHMEM 0x08000 /* DB_SHMEM specified. */
#define B_DB_TXN 0x10000 /* DB_TXN specified. */
u_int32_t flags;
} BTREE;
#include "extern.h"
+70
View File
@@ -0,0 +1,70 @@
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)extern.h 8.10 (Berkeley) 7/20/94
*/
int __bt_close __P((DB *));
int __bt_cmp __P((BTREE *, const DBT *, EPG *));
int __bt_crsrdel __P((BTREE *, EPGNO *));
int __bt_defcmp __P((const DBT *, const DBT *));
size_t __bt_defpfx __P((const DBT *, const DBT *));
int __bt_delete __P((const DB *, const DBT *, u_int));
int __bt_dleaf __P((BTREE *, const DBT *, PAGE *, u_int));
int __bt_fd __P((const DB *));
int __bt_free __P((BTREE *, PAGE *));
int __bt_get __P((const DB *, const DBT *, DBT *, u_int));
PAGE *__bt_new __P((BTREE *, pgno_t *));
void __bt_pgin __P((void *, pgno_t, void *));
void __bt_pgout __P((void *, pgno_t, void *));
int __bt_push __P((BTREE *, pgno_t, int));
int __bt_put __P((const DB *dbp, DBT *, const DBT *, u_int));
int __bt_ret __P((BTREE *, EPG *, DBT *, DBT *, DBT *, DBT *, int));
EPG *__bt_search __P((BTREE *, const DBT *, int *));
int __bt_seq __P((const DB *, DBT *, DBT *, u_int));
void __bt_setcur __P((BTREE *, pgno_t, u_int));
int __bt_split __P((BTREE *, PAGE *,
const DBT *, const DBT *, int, size_t, u_int32_t));
int __bt_sync __P((const DB *, u_int));
int __ovfl_delete __P((BTREE *, void *));
int __ovfl_get __P((BTREE *, void *, size_t *, void **, size_t *));
int __ovfl_put __P((BTREE *, const DBT *, pgno_t *));
#ifdef DEBUG
void __bt_dnpage __P((DB *, pgno_t));
void __bt_dpage __P((PAGE *));
void __bt_dump __P((DB *));
#endif
#ifdef STATISTICS
void __bt_stat __P((DB *));
#endif
+49
View File
@@ -0,0 +1,49 @@
/* Values for building 4.4 BSD db routines in the GNU C library. */
#ifndef _compat_h_
#define _compat_h_
#include <fcntl.h>
/*
* If you can't provide lock values in the open(2) call. Note, this
* allows races to happen.
*/
#ifndef O_EXLOCK /* 4.4BSD extension. */
#define O_EXLOCK 0
#endif
#ifndef O_SHLOCK /* 4.4BSD extension. */
#define O_SHLOCK 0
#endif
#include <errno.h>
#ifndef EFTYPE
#define EFTYPE EINVAL /* POSIX 1003.1 format errno. */
#endif
#include <unistd.h>
#include <limits.h>
#ifndef _POSIX_VDISABLE /* POSIX 1003.1 disabling char. */
#define _POSIX_VDISABLE 0 /* Some systems used 0. */
#endif
#include <termios.h>
#ifndef TCSASOFT /* 4.4BSD extension. */
#define TCSASOFT 0
#endif
#include <sys/param.h>
#ifndef MAX /* Usually found in <sys/param.h>. */
#define MAX(_a,_b) ((_a)<(_b)?(_b):(_a))
#endif
#ifndef MIN /* Usually found in <sys/param.h>. */
#define MIN(_a,_b) ((_a)<(_b)?(_a):(_b))
#endif
#endif /* compat.h */
+236
View File
@@ -0,0 +1,236 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)db.h 8.7 (Berkeley) 6/16/94
*/
#ifndef _DB_H_
#define _DB_H_
#include <sys/types.h>
#include <sys/cdefs.h>
#include <limits.h>
#ifdef __DBINTERFACE_PRIVATE
#include <compat.h>
#endif
#define RET_ERROR -1 /* Return values. */
#define RET_SUCCESS 0
#define RET_SPECIAL 1
#ifndef __BIT_TYPES_DEFINED__
#define __BIT_TYPES_DEFINED__
typedef __signed char int8_t;
typedef unsigned char u_int8_t;
typedef short int16_t;
typedef unsigned short u_int16_t;
typedef int int32_t;
typedef unsigned int u_int32_t;
#ifdef WE_DONT_NEED_QUADS
typedef long long int64_t;
typedef unsigned long long u_int64_t;
#endif
#endif
#define MAX_PAGE_NUMBER 0xffffffff /* >= # of pages in a file */
typedef u_int32_t pgno_t;
#define MAX_PAGE_OFFSET 65535 /* >= # of bytes in a page */
typedef u_int16_t indx_t;
#define MAX_REC_NUMBER 0xffffffff /* >= # of records in a tree */
typedef u_int32_t recno_t;
/* Key/data structure -- a Data-Base Thang. */
typedef struct {
void *data; /* data */
size_t size; /* data length */
} DBT;
/* Routine flags. */
#define R_CURSOR 1 /* del, put, seq */
#define __R_UNUSED 2 /* UNUSED */
#define R_FIRST 3 /* seq */
#define R_IAFTER 4 /* put (RECNO) */
#define R_IBEFORE 5 /* put (RECNO) */
#define R_LAST 6 /* seq (BTREE, RECNO) */
#define R_NEXT 7 /* seq */
#define R_NOOVERWRITE 8 /* put */
#define R_PREV 9 /* seq (BTREE, RECNO) */
#define R_SETCURSOR 10 /* put (RECNO) */
#define R_RECNOSYNC 11 /* sync (RECNO) */
typedef enum { DB_BTREE, DB_HASH, DB_RECNO } DBTYPE;
/*
* !!!
* The following flags are included in the dbopen(3) call as part of the
* open(2) flags. In order to avoid conflicts with the open flags, start
* at the top of the 16 or 32-bit number space and work our way down. If
* the open flags were significantly expanded in the future, it could be
* a problem. Wish I'd left another flags word in the dbopen call.
*
* !!!
* None of this stuff is implemented yet. The only reason that it's here
* is so that the access methods can skip copying the key/data pair when
* the DB_LOCK flag isn't set.
*/
#if UINT_MAX > 65535
#define DB_LOCK 0x20000000 /* Do locking. */
#define DB_SHMEM 0x40000000 /* Use shared memory. */
#define DB_TXN 0x80000000 /* Do transactions. */
#else
#define DB_LOCK 0x2000 /* Do locking. */
#define DB_SHMEM 0x4000 /* Use shared memory. */
#define DB_TXN 0x8000 /* Do transactions. */
#endif
/* Access method description structure. */
typedef struct __db {
DBTYPE type; /* Underlying db type. */
int (*close) __P((struct __db *));
int (*del) __P((const struct __db *, const DBT *, u_int));
int (*get) __P((const struct __db *, const DBT *, DBT *, u_int));
int (*put) __P((const struct __db *, DBT *, const DBT *, u_int));
int (*seq) __P((const struct __db *, DBT *, DBT *, u_int));
int (*sync) __P((const struct __db *, u_int));
void *internal; /* Access method private. */
int (*fd) __P((const struct __db *));
} DB;
#define BTREEMAGIC 0x053162
#define BTREEVERSION 3
/* Structure used to pass parameters to the btree routines. */
typedef struct {
#define R_DUP 0x01 /* duplicate keys */
u_long flags;
u_int cachesize; /* bytes to cache */
int maxkeypage; /* maximum keys per page */
int minkeypage; /* minimum keys per page */
u_int psize; /* page size */
int (*compare) /* comparison function */
__P((const DBT *, const DBT *));
size_t (*prefix) /* prefix function */
__P((const DBT *, const DBT *));
int lorder; /* byte order */
} BTREEINFO;
#define HASHMAGIC 0x061561
#define HASHVERSION 2
/* Structure used to pass parameters to the hashing routines. */
typedef struct {
u_int bsize; /* bucket size */
u_int ffactor; /* fill factor */
u_int nelem; /* number of elements */
u_int cachesize; /* bytes to cache */
u_int32_t /* hash function */
(*hash) __P((const void *, size_t));
int lorder; /* byte order */
} HASHINFO;
/* Structure used to pass parameters to the record routines. */
typedef struct {
#define R_FIXEDLEN 0x01 /* fixed-length records */
#define R_NOKEY 0x02 /* key not required */
#define R_SNAPSHOT 0x04 /* snapshot the input */
u_long flags;
u_int cachesize; /* bytes to cache */
u_int psize; /* page size */
int lorder; /* byte order */
size_t reclen; /* record length (fixed-length records) */
u_char bval; /* delimiting byte (variable-length records */
char *bfname; /* btree file name */
} RECNOINFO;
#ifdef __DBINTERFACE_PRIVATE
/*
* Little endian <==> big endian 32-bit swap macros.
* M_32_SWAP swap a memory location
* P_32_SWAP swap a referenced memory location
* P_32_COPY swap from one location to another
*/
#define M_32_SWAP(a) { \
u_int32_t _tmp = a; \
((char *)&a)[0] = ((char *)&_tmp)[3]; \
((char *)&a)[1] = ((char *)&_tmp)[2]; \
((char *)&a)[2] = ((char *)&_tmp)[1]; \
((char *)&a)[3] = ((char *)&_tmp)[0]; \
}
#define P_32_SWAP(a) { \
u_int32_t _tmp = *(u_int32_t *)a; \
((char *)a)[0] = ((char *)&_tmp)[3]; \
((char *)a)[1] = ((char *)&_tmp)[2]; \
((char *)a)[2] = ((char *)&_tmp)[1]; \
((char *)a)[3] = ((char *)&_tmp)[0]; \
}
#define P_32_COPY(a, b) { \
((char *)&(b))[0] = ((char *)&(a))[3]; \
((char *)&(b))[1] = ((char *)&(a))[2]; \
((char *)&(b))[2] = ((char *)&(a))[1]; \
((char *)&(b))[3] = ((char *)&(a))[0]; \
}
/*
* Little endian <==> big endian 16-bit swap macros.
* M_16_SWAP swap a memory location
* P_16_SWAP swap a referenced memory location
* P_16_COPY swap from one location to another
*/
#define M_16_SWAP(a) { \
u_int16_t _tmp = a; \
((char *)&a)[0] = ((char *)&_tmp)[1]; \
((char *)&a)[1] = ((char *)&_tmp)[0]; \
}
#define P_16_SWAP(a) { \
u_int16_t _tmp = *(u_int16_t *)a; \
((char *)a)[0] = ((char *)&_tmp)[1]; \
((char *)a)[1] = ((char *)&_tmp)[0]; \
}
#define P_16_COPY(a, b) { \
((char *)&(b))[0] = ((char *)&(a))[1]; \
((char *)&(b))[1] = ((char *)&(a))[0]; \
}
#endif
__BEGIN_DECLS
DB *dbopen __P((const char *, int, int, DBTYPE, const void *));
#ifdef __DBINTERFACE_PRIVATE
DB *__bt_open __P((const char *, int, int, const BTREEINFO *, int));
DB *__hash_open __P((const char *, int, int, const HASHINFO *, int));
DB *__rec_open __P((const char *, int, int, const RECNOINFO *, int));
void __dbpanic __P((DB *dbp));
#endif
__END_DECLS
#endif /* !_DB_H_ */
+103
View File
@@ -0,0 +1,103 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)db.c 8.4 (Berkeley) 2/21/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <db.h>
DB *
dbopen(fname, flags, mode, type, openinfo)
const char *fname;
int flags, mode;
DBTYPE type;
const void *openinfo;
{
#define DB_FLAGS (DB_LOCK | DB_SHMEM | DB_TXN)
#define USE_OPEN_FLAGS \
(O_CREAT | O_EXCL | O_EXLOCK | O_NONBLOCK | O_RDONLY | \
O_RDWR | O_SHLOCK | O_TRUNC)
if ((flags & ~(USE_OPEN_FLAGS | DB_FLAGS)) == 0)
switch (type) {
case DB_BTREE:
return (__bt_open(fname, flags & USE_OPEN_FLAGS,
mode, openinfo, flags & DB_FLAGS));
case DB_HASH:
return (__hash_open(fname, flags & USE_OPEN_FLAGS,
mode, openinfo, flags & DB_FLAGS));
case DB_RECNO:
return (__rec_open(fname, flags & USE_OPEN_FLAGS,
mode, openinfo, flags & DB_FLAGS));
}
errno = EINVAL;
return (NULL);
}
static int
__dberr __P((void))
{
return (RET_ERROR);
}
/*
* __DBPANIC -- Stop.
*
* Parameters:
* dbp: pointer to the DB structure.
*/
void
__dbpanic(dbp)
DB *dbp;
{
/* The only thing that can succeed is a close. */
dbp->del = (int (*)__P((const struct __db *,
const DBT *, u_int))) __dberr;
dbp->get = (int (*)__P((const struct __db *,
const DBT *, DBT *, u_int))) __dberr;
dbp->put = (int (*)__P((const struct __db *,
DBT *, const DBT *, u_int))) __dberr;
dbp->seq = (int (*)__P((const struct __db *,
DBT *, DBT *, u_int))) __dberr;
dbp->sync = (int (*)__P((const struct __db *, u_int))) __dberr;
dbp->fd = (int (*)__P((const struct __db *))) __dberr;
}
+65
View File
@@ -0,0 +1,65 @@
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)extern.h 8.4 (Berkeley) 6/16/94
*/
BUFHEAD *__add_ovflpage __P((HTAB *, BUFHEAD *));
int __addel __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
int __big_delete __P((HTAB *, BUFHEAD *));
int __big_insert __P((HTAB *, BUFHEAD *, const DBT *, const DBT *));
int __big_keydata __P((HTAB *, BUFHEAD *, DBT *, DBT *, int));
int __big_return __P((HTAB *, BUFHEAD *, int, DBT *, int));
int __big_split __P((HTAB *, BUFHEAD *, BUFHEAD *, BUFHEAD *,
int, u_int32_t, SPLIT_RETURN *));
int __buf_free __P((HTAB *, int, int));
void __buf_init __P((HTAB *, int));
u_int32_t __call_hash __P((HTAB *, char *, int));
int __delpair __P((HTAB *, BUFHEAD *, int));
int __expand_table __P((HTAB *));
int __find_bigpair __P((HTAB *, BUFHEAD *, int, char *, int));
u_int16_t __find_last_page __P((HTAB *, BUFHEAD **));
void __free_ovflpage __P((HTAB *, BUFHEAD *));
BUFHEAD *__get_buf __P((HTAB *, u_int32_t, BUFHEAD *, int));
int __get_page __P((HTAB *, char *, u_int32_t, int, int, int));
int __ibitmap __P((HTAB *, int, int, int));
u_int32_t __log2 __P((u_int32_t));
int __put_page __P((HTAB *, char *, u_int32_t, int, int));
void __reclaim_buf __P((HTAB *, BUFHEAD *));
int __split_page __P((HTAB *, u_int32_t, u_int32_t));
/* Default hash routine. */
extern u_int32_t (*__default_hash) __P((const void *, size_t));
#ifdef HASH_STATISTICS
extern int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
#endif
+994
View File
@@ -0,0 +1,994 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash.c 8.9 (Berkeley) 6/16/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef DEBUG
#include <assert.h>
#endif
#include <db.h>
#include "hash.h"
#include "page.h"
#include "extern.h"
static int alloc_segs __P((HTAB *, int));
static int flush_meta __P((HTAB *));
static int hash_access __P((HTAB *, ACTION, DBT *, DBT *));
static int hash_close __P((DB *));
static int hash_delete __P((const DB *, const DBT *, u_int32_t));
static int hash_fd __P((const DB *));
static int hash_get __P((const DB *, const DBT *, DBT *, u_int32_t));
static int hash_put __P((const DB *, DBT *, const DBT *, u_int32_t));
static void *hash_realloc __P((SEGMENT **, int, int));
static int hash_seq __P((const DB *, DBT *, DBT *, u_int32_t));
static int hash_sync __P((const DB *, u_int32_t));
static int hdestroy __P((HTAB *));
static HTAB *init_hash __P((HTAB *, const char *, HASHINFO *));
static int init_htab __P((HTAB *, int));
#if BYTE_ORDER == LITTLE_ENDIAN
static void swap_header __P((HTAB *));
static void swap_header_copy __P((HASHHDR *, HASHHDR *));
#endif
/* Fast arithmetic, relying on powers of 2, */
#define MOD(x, y) ((x) & ((y) - 1))
#define RETURN_ERROR(ERR, LOC) { save_errno = ERR; goto LOC; }
/* Return values */
#define SUCCESS (0)
#define ERROR (-1)
#define ABNORMAL (1)
#ifdef HASH_STATISTICS
int hash_accesses, hash_collisions, hash_expansions, hash_overflows;
#endif
/************************** INTERFACE ROUTINES ***************************/
/* OPEN/CLOSE */
extern DB *
__hash_open(file, flags, mode, info, dflags)
const char *file;
int flags, mode, dflags;
const HASHINFO *info; /* Special directives for create */
{
HTAB *hashp;
struct stat statbuf;
DB *dbp;
int bpages, hdrsize, new_table, nsegs, save_errno;
if ((flags & O_ACCMODE) == O_WRONLY) {
errno = EINVAL;
return (NULL);
}
if (!(hashp = (HTAB *)calloc(1, sizeof(HTAB))))
return (NULL);
hashp->fp = -1;
/*
* Even if user wants write only, we need to be able to read
* the actual file, so we need to open it read/write. But, the
* field in the hashp structure needs to be accurate so that
* we can check accesses.
*/
hashp->flags = flags;
new_table = 0;
if (!file || (flags & O_TRUNC) ||
(stat(file, &statbuf) && (errno == ENOENT))) {
if (errno == ENOENT)
errno = 0; /* Just in case someone looks at errno */
new_table = 1;
}
if (file) {
if ((hashp->fp = open(file, flags, mode)) == -1)
RETURN_ERROR(errno, error0);
(void)fcntl(hashp->fp, F_SETFD, 1);
}
if (new_table) {
if (!(hashp = init_hash(hashp, file, (HASHINFO *)info)))
RETURN_ERROR(errno, error1);
} else {
/* Table already exists */
if (info && info->hash)
hashp->hash = info->hash;
else
hashp->hash = __default_hash;
hdrsize = read(hashp->fp, &hashp->hdr, sizeof(HASHHDR));
#if BYTE_ORDER == LITTLE_ENDIAN
swap_header(hashp);
#endif
if (hdrsize == -1)
RETURN_ERROR(errno, error1);
if (hdrsize != sizeof(HASHHDR))
RETURN_ERROR(EFTYPE, error1);
/* Verify file type, versions and hash function */
if (hashp->MAGIC != HASHMAGIC)
RETURN_ERROR(EFTYPE, error1);
#define OLDHASHVERSION 1
if (hashp->VERSION != HASHVERSION &&
hashp->VERSION != OLDHASHVERSION)
RETURN_ERROR(EFTYPE, error1);
if (hashp->hash(CHARKEY, sizeof(CHARKEY)) != hashp->H_CHARKEY)
RETURN_ERROR(EFTYPE, error1);
/*
* Figure out how many segments we need. Max_Bucket is the
* maximum bucket number, so the number of buckets is
* max_bucket + 1.
*/
nsegs = (hashp->MAX_BUCKET + 1 + hashp->SGSIZE - 1) /
hashp->SGSIZE;
hashp->nsegs = 0;
if (alloc_segs(hashp, nsegs))
/*
* If alloc_segs fails, table will have been destroyed
* and errno will have been set.
*/
return (NULL);
/* Read in bitmaps */
bpages = (hashp->SPARES[hashp->OVFL_POINT] +
(hashp->BSIZE << BYTE_SHIFT) - 1) >>
(hashp->BSHIFT + BYTE_SHIFT);
hashp->nmaps = bpages;
(void)memset(&hashp->mapp[0], 0, bpages * sizeof(u_int32_t *));
}
/* Initialize Buffer Manager */
if (info && info->cachesize)
__buf_init(hashp, info->cachesize);
else
__buf_init(hashp, DEF_BUFSIZE);
hashp->new_file = new_table;
hashp->save_file = file && (hashp->flags & O_RDWR);
hashp->cbucket = -1;
if (!(dbp = (DB *)malloc(sizeof(DB)))) {
save_errno = errno;
hdestroy(hashp);
errno = save_errno;
return (NULL);
}
dbp->internal = hashp;
dbp->close = hash_close;
dbp->del = hash_delete;
dbp->fd = hash_fd;
dbp->get = hash_get;
dbp->put = hash_put;
dbp->seq = hash_seq;
dbp->sync = hash_sync;
dbp->type = DB_HASH;
#ifdef DEBUG
(void)fprintf(stderr,
"%s\n%s%x\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%x\n%s%x\n%s%d\n%s%d\n",
"init_htab:",
"TABLE POINTER ", hashp,
"BUCKET SIZE ", hashp->BSIZE,
"BUCKET SHIFT ", hashp->BSHIFT,
"DIRECTORY SIZE ", hashp->DSIZE,
"SEGMENT SIZE ", hashp->SGSIZE,
"SEGMENT SHIFT ", hashp->SSHIFT,
"FILL FACTOR ", hashp->FFACTOR,
"MAX BUCKET ", hashp->MAX_BUCKET,
"OVFL POINT ", hashp->OVFL_POINT,
"LAST FREED ", hashp->LAST_FREED,
"HIGH MASK ", hashp->HIGH_MASK,
"LOW MASK ", hashp->LOW_MASK,
"NSEGS ", hashp->nsegs,
"NKEYS ", hashp->NKEYS);
#endif
#ifdef HASH_STATISTICS
hash_overflows = hash_accesses = hash_collisions = hash_expansions = 0;
#endif
return (dbp);
error1:
if (hashp != NULL)
(void)close(hashp->fp);
error0:
free(hashp);
errno = save_errno;
return (NULL);
}
static int
hash_close(dbp)
DB *dbp;
{
HTAB *hashp;
int retval;
if (!dbp)
return (ERROR);
hashp = (HTAB *)dbp->internal;
retval = hdestroy(hashp);
free(dbp);
return (retval);
}
static int
hash_fd(dbp)
const DB *dbp;
{
HTAB *hashp;
if (!dbp)
return (ERROR);
hashp = (HTAB *)dbp->internal;
if (hashp->fp == -1) {
errno = ENOENT;
return (-1);
}
return (hashp->fp);
}
/************************** LOCAL CREATION ROUTINES **********************/
static HTAB *
init_hash(hashp, file, info)
HTAB *hashp;
const char *file;
HASHINFO *info;
{
struct stat statbuf;
int nelem;
nelem = 1;
hashp->NKEYS = 0;
hashp->LORDER = BYTE_ORDER;
hashp->BSIZE = DEF_BUCKET_SIZE;
hashp->BSHIFT = DEF_BUCKET_SHIFT;
hashp->SGSIZE = DEF_SEGSIZE;
hashp->SSHIFT = DEF_SEGSIZE_SHIFT;
hashp->DSIZE = DEF_DIRSIZE;
hashp->FFACTOR = DEF_FFACTOR;
hashp->hash = __default_hash;
memset(hashp->SPARES, 0, sizeof(hashp->SPARES));
memset(hashp->BITMAPS, 0, sizeof (hashp->BITMAPS));
/* Fix bucket size to be optimal for file system */
if (file != NULL) {
if (stat(file, &statbuf))
return (NULL);
hashp->BSIZE = statbuf.st_blksize;
hashp->BSHIFT = __log2(hashp->BSIZE);
}
if (info) {
if (info->bsize) {
/* Round pagesize up to power of 2 */
hashp->BSHIFT = __log2(info->bsize);
hashp->BSIZE = 1 << hashp->BSHIFT;
if (hashp->BSIZE > MAX_BSIZE) {
errno = EINVAL;
return (NULL);
}
}
if (info->ffactor)
hashp->FFACTOR = info->ffactor;
if (info->hash)
hashp->hash = info->hash;
if (info->nelem)
nelem = info->nelem;
if (info->lorder) {
if (info->lorder != BIG_ENDIAN &&
info->lorder != LITTLE_ENDIAN) {
errno = EINVAL;
return (NULL);
}
hashp->LORDER = info->lorder;
}
}
/* init_htab should destroy the table and set errno if it fails */
if (init_htab(hashp, nelem))
return (NULL);
else
return (hashp);
}
/*
* This calls alloc_segs which may run out of memory. Alloc_segs will destroy
* the table and set errno, so we just pass the error information along.
*
* Returns 0 on No Error
*/
static int
init_htab(hashp, nelem)
HTAB *hashp;
int nelem;
{
register int nbuckets, nsegs;
int l2;
/*
* Divide number of elements by the fill factor and determine a
* desired number of buckets. Allocate space for the next greater
* power of two number of buckets.
*/
nelem = (nelem - 1) / hashp->FFACTOR + 1;
l2 = __log2(MAX(nelem, 2));
nbuckets = 1 << l2;
hashp->SPARES[l2] = l2 + 1;
hashp->SPARES[l2 + 1] = l2 + 1;
hashp->OVFL_POINT = l2;
hashp->LAST_FREED = 2;
/* First bitmap page is at: splitpoint l2 page offset 1 */
if (__ibitmap(hashp, OADDR_OF(l2, 1), l2 + 1, 0))
return (-1);
hashp->MAX_BUCKET = hashp->LOW_MASK = nbuckets - 1;
hashp->HIGH_MASK = (nbuckets << 1) - 1;
hashp->HDRPAGES = ((MAX(sizeof(HASHHDR), MINHDRSIZE) - 1) >>
hashp->BSHIFT) + 1;
nsegs = (nbuckets - 1) / hashp->SGSIZE + 1;
nsegs = 1 << __log2(nsegs);
if (nsegs > hashp->DSIZE)
hashp->DSIZE = nsegs;
return (alloc_segs(hashp, nsegs));
}
/********************** DESTROY/CLOSE ROUTINES ************************/
/*
* Flushes any changes to the file if necessary and destroys the hashp
* structure, freeing all allocated space.
*/
static int
hdestroy(hashp)
HTAB *hashp;
{
int i, save_errno;
save_errno = 0;
#ifdef HASH_STATISTICS
(void)fprintf(stderr, "hdestroy: accesses %ld collisions %ld\n",
hash_accesses, hash_collisions);
(void)fprintf(stderr, "hdestroy: expansions %ld\n",
hash_expansions);
(void)fprintf(stderr, "hdestroy: overflows %ld\n",
hash_overflows);
(void)fprintf(stderr, "keys %ld maxp %d segmentcount %d\n",
hashp->NKEYS, hashp->MAX_BUCKET, hashp->nsegs);
for (i = 0; i < NCACHED; i++)
(void)fprintf(stderr,
"spares[%d] = %d\n", i, hashp->SPARES[i]);
#endif
/*
* Call on buffer manager to free buffers, and if required,
* write them to disk.
*/
if (__buf_free(hashp, 1, hashp->save_file))
save_errno = errno;
if (hashp->dir) {
free(*hashp->dir); /* Free initial segments */
/* Free extra segments */
while (hashp->exsegs--)
free(hashp->dir[--hashp->nsegs]);
free(hashp->dir);
}
if (flush_meta(hashp) && !save_errno)
save_errno = errno;
/* Free Bigmaps */
for (i = 0; i < hashp->nmaps; i++)
if (hashp->mapp[i])
free(hashp->mapp[i]);
if (hashp->fp != -1)
(void)close(hashp->fp);
free(hashp);
if (save_errno) {
errno = save_errno;
return (ERROR);
}
return (SUCCESS);
}
/*
* Write modified pages to disk
*
* Returns:
* 0 == OK
* -1 ERROR
*/
static int
hash_sync(dbp, flags)
const DB *dbp;
u_int32_t flags;
{
HTAB *hashp;
if (flags != 0) {
errno = EINVAL;
return (ERROR);
}
if (!dbp)
return (ERROR);
hashp = (HTAB *)dbp->internal;
if (!hashp->save_file)
return (0);
if (__buf_free(hashp, 0, 1) || flush_meta(hashp))
return (ERROR);
hashp->new_file = 0;
return (0);
}
/*
* Returns:
* 0 == OK
* -1 indicates that errno should be set
*/
static int
flush_meta(hashp)
HTAB *hashp;
{
HASHHDR *whdrp;
#if BYTE_ORDER == LITTLE_ENDIAN
HASHHDR whdr;
#endif
int fp, i, wsize;
if (!hashp->save_file)
return (0);
hashp->MAGIC = HASHMAGIC;
hashp->VERSION = HASHVERSION;
hashp->H_CHARKEY = hashp->hash(CHARKEY, sizeof(CHARKEY));
fp = hashp->fp;
whdrp = &hashp->hdr;
#if BYTE_ORDER == LITTLE_ENDIAN
whdrp = &whdr;
swap_header_copy(&hashp->hdr, whdrp);
#endif
if ((lseek(fp, (off_t)0, SEEK_SET) == -1) ||
((wsize = write(fp, whdrp, sizeof(HASHHDR))) == -1))
return (-1);
else
if (wsize != sizeof(HASHHDR)) {
errno = EFTYPE;
hashp->errnum = errno;
return (-1);
}
for (i = 0; i < NCACHED; i++)
if (hashp->mapp[i])
if (__put_page(hashp, (char *)hashp->mapp[i],
hashp->BITMAPS[i], 0, 1))
return (-1);
return (0);
}
/*******************************SEARCH ROUTINES *****************************/
/*
* All the access routines return
*
* Returns:
* 0 on SUCCESS
* 1 to indicate an external ERROR (i.e. key not found, etc)
* -1 to indicate an internal ERROR (i.e. out of memory, etc)
*/
static int
hash_get(dbp, key, data, flag)
const DB *dbp;
const DBT *key;
DBT *data;
u_int32_t flag;
{
HTAB *hashp;
hashp = (HTAB *)dbp->internal;
if (flag) {
hashp->errnum = errno = EINVAL;
return (ERROR);
}
return (hash_access(hashp, HASH_GET, (DBT *)key, data));
}
static int
hash_put(dbp, key, data, flag)
const DB *dbp;
DBT *key;
const DBT *data;
u_int32_t flag;
{
HTAB *hashp;
hashp = (HTAB *)dbp->internal;
if (flag && flag != R_NOOVERWRITE) {
hashp->errnum = errno = EINVAL;
return (ERROR);
}
if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
hashp->errnum = errno = EPERM;
return (ERROR);
}
return (hash_access(hashp, flag == R_NOOVERWRITE ?
HASH_PUTNEW : HASH_PUT, (DBT *)key, (DBT *)data));
}
static int
hash_delete(dbp, key, flag)
const DB *dbp;
const DBT *key;
u_int32_t flag; /* Ignored */
{
HTAB *hashp;
hashp = (HTAB *)dbp->internal;
if (flag && flag != R_CURSOR) {
hashp->errnum = errno = EINVAL;
return (ERROR);
}
if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
hashp->errnum = errno = EPERM;
return (ERROR);
}
return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
}
/*
* Assume that hashp has been set in wrapper routine.
*/
static int
hash_access(hashp, action, key, val)
HTAB *hashp;
ACTION action;
DBT *key, *val;
{
register BUFHEAD *rbufp;
BUFHEAD *bufp, *save_bufp;
register u_int16_t *bp;
register int n, ndx, off, size;
register char *kp;
u_int16_t pageno;
#ifdef HASH_STATISTICS
hash_accesses++;
#endif
off = hashp->BSIZE;
size = key->size;
kp = (char *)key->data;
rbufp = __get_buf(hashp, __call_hash(hashp, kp, size), NULL, 0);
if (!rbufp)
return (ERROR);
save_bufp = rbufp;
/* Pin the bucket chain */
rbufp->flags |= BUF_PIN;
for (bp = (u_int16_t *)rbufp->page, n = *bp++, ndx = 1; ndx < n;)
if (bp[1] >= REAL_KEY) {
/* Real key/data pair */
if (size == off - *bp &&
memcmp(kp, rbufp->page + *bp, size) == 0)
goto found;
off = bp[1];
#ifdef HASH_STATISTICS
hash_collisions++;
#endif
bp += 2;
ndx += 2;
} else if (bp[1] == OVFLPAGE) {
rbufp = __get_buf(hashp, *bp, rbufp, 0);
if (!rbufp) {
save_bufp->flags &= ~BUF_PIN;
return (ERROR);
}
/* FOR LOOP INIT */
bp = (u_int16_t *)rbufp->page;
n = *bp++;
ndx = 1;
off = hashp->BSIZE;
} else if (bp[1] < REAL_KEY) {
if ((ndx =
__find_bigpair(hashp, rbufp, ndx, kp, size)) > 0)
goto found;
if (ndx == -2) {
bufp = rbufp;
if (!(pageno =
__find_last_page(hashp, &bufp))) {
ndx = 0;
rbufp = bufp;
break; /* FOR */
}
rbufp = __get_buf(hashp, pageno, bufp, 0);
if (!rbufp) {
save_bufp->flags &= ~BUF_PIN;
return (ERROR);
}
/* FOR LOOP INIT */
bp = (u_int16_t *)rbufp->page;
n = *bp++;
ndx = 1;
off = hashp->BSIZE;
} else {
save_bufp->flags &= ~BUF_PIN;
return (ERROR);
}
}
/* Not found */
switch (action) {
case HASH_PUT:
case HASH_PUTNEW:
if (__addel(hashp, rbufp, key, val)) {
save_bufp->flags &= ~BUF_PIN;
return (ERROR);
} else {
save_bufp->flags &= ~BUF_PIN;
return (SUCCESS);
}
case HASH_GET:
case HASH_DELETE:
default:
save_bufp->flags &= ~BUF_PIN;
return (ABNORMAL);
}
found:
switch (action) {
case HASH_PUTNEW:
save_bufp->flags &= ~BUF_PIN;
return (ABNORMAL);
case HASH_GET:
bp = (u_int16_t *)rbufp->page;
if (bp[ndx + 1] < REAL_KEY) {
if (__big_return(hashp, rbufp, ndx, val, 0))
return (ERROR);
} else {
val->data = (u_char *)rbufp->page + (int)bp[ndx + 1];
val->size = bp[ndx] - bp[ndx + 1];
}
break;
case HASH_PUT:
if ((__delpair(hashp, rbufp, ndx)) ||
(__addel(hashp, rbufp, key, val))) {
save_bufp->flags &= ~BUF_PIN;
return (ERROR);
}
break;
case HASH_DELETE:
if (__delpair(hashp, rbufp, ndx))
return (ERROR);
break;
default:
abort();
}
save_bufp->flags &= ~BUF_PIN;
return (SUCCESS);
}
static int
hash_seq(dbp, key, data, flag)
const DB *dbp;
DBT *key, *data;
u_int32_t flag;
{
register u_int32_t bucket;
register BUFHEAD *bufp;
HTAB *hashp;
u_int16_t *bp, ndx;
hashp = (HTAB *)dbp->internal;
if (flag && flag != R_FIRST && flag != R_NEXT) {
hashp->errnum = errno = EINVAL;
return (ERROR);
}
#ifdef HASH_STATISTICS
hash_accesses++;
#endif
if ((hashp->cbucket < 0) || (flag == R_FIRST)) {
hashp->cbucket = 0;
hashp->cndx = 1;
hashp->cpage = NULL;
}
for (bp = NULL; !bp || !bp[0]; ) {
if (!(bufp = hashp->cpage)) {
for (bucket = hashp->cbucket;
bucket <= hashp->MAX_BUCKET;
bucket++, hashp->cndx = 1) {
bufp = __get_buf(hashp, bucket, NULL, 0);
if (!bufp)
return (ERROR);
hashp->cpage = bufp;
bp = (u_int16_t *)bufp->page;
if (bp[0])
break;
}
hashp->cbucket = bucket;
if (hashp->cbucket > hashp->MAX_BUCKET) {
hashp->cbucket = -1;
return (ABNORMAL);
}
} else
bp = (u_int16_t *)hashp->cpage->page;
#ifdef DEBUG
assert(bp);
assert(bufp);
#endif
while (bp[hashp->cndx + 1] == OVFLPAGE) {
bufp = hashp->cpage =
__get_buf(hashp, bp[hashp->cndx], bufp, 0);
if (!bufp)
return (ERROR);
bp = (u_int16_t *)(bufp->page);
hashp->cndx = 1;
}
if (!bp[0]) {
hashp->cpage = NULL;
++hashp->cbucket;
}
}
ndx = hashp->cndx;
if (bp[ndx + 1] < REAL_KEY) {
if (__big_keydata(hashp, bufp, key, data, 1))
return (ERROR);
} else {
key->data = (u_char *)hashp->cpage->page + bp[ndx];
key->size = (ndx > 1 ? bp[ndx - 1] : hashp->BSIZE) - bp[ndx];
data->data = (u_char *)hashp->cpage->page + bp[ndx + 1];
data->size = bp[ndx] - bp[ndx + 1];
ndx += 2;
if (ndx > bp[0]) {
hashp->cpage = NULL;
hashp->cbucket++;
hashp->cndx = 1;
} else
hashp->cndx = ndx;
}
return (SUCCESS);
}
/********************************* UTILITIES ************************/
/*
* Returns:
* 0 ==> OK
* -1 ==> Error
*/
extern int
__expand_table(hashp)
HTAB *hashp;
{
u_int32_t old_bucket, new_bucket;
int dirsize, new_segnum, spare_ndx;
#ifdef HASH_STATISTICS
hash_expansions++;
#endif
new_bucket = ++hashp->MAX_BUCKET;
old_bucket = (hashp->MAX_BUCKET & hashp->LOW_MASK);
new_segnum = new_bucket >> hashp->SSHIFT;
/* Check if we need a new segment */
if (new_segnum >= hashp->nsegs) {
/* Check if we need to expand directory */
if (new_segnum >= hashp->DSIZE) {
/* Reallocate directory */
dirsize = hashp->DSIZE * sizeof(SEGMENT *);
if (!hash_realloc(&hashp->dir, dirsize, dirsize << 1))
return (-1);
hashp->DSIZE = dirsize << 1;
}
if ((hashp->dir[new_segnum] =
(SEGMENT)calloc(hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
return (-1);
hashp->exsegs++;
hashp->nsegs++;
}
/*
* If the split point is increasing (MAX_BUCKET's log base 2
* * increases), we need to copy the current contents of the spare
* split bucket to the next bucket.
*/
spare_ndx = __log2(hashp->MAX_BUCKET + 1);
if (spare_ndx > hashp->OVFL_POINT) {
hashp->SPARES[spare_ndx] = hashp->SPARES[hashp->OVFL_POINT];
hashp->OVFL_POINT = spare_ndx;
}
if (new_bucket > hashp->HIGH_MASK) {
/* Starting a new doubling */
hashp->LOW_MASK = hashp->HIGH_MASK;
hashp->HIGH_MASK = new_bucket | hashp->LOW_MASK;
}
/* Relocate records to the new bucket */
return (__split_page(hashp, old_bucket, new_bucket));
}
/*
* If realloc guarantees that the pointer is not destroyed if the realloc
* fails, then this routine can go away.
*/
static void *
hash_realloc(p_ptr, oldsize, newsize)
SEGMENT **p_ptr;
int oldsize, newsize;
{
register void *p;
if (p = malloc(newsize)) {
memmove(p, *p_ptr, oldsize);
memset((char *)p + oldsize, 0, newsize - oldsize);
free(*p_ptr);
*p_ptr = p;
}
return (p);
}
extern u_int32_t
__call_hash(hashp, k, len)
HTAB *hashp;
char *k;
int len;
{
int n, bucket;
n = hashp->hash(k, len);
bucket = n & hashp->HIGH_MASK;
if (bucket > hashp->MAX_BUCKET)
bucket = bucket & hashp->LOW_MASK;
return (bucket);
}
/*
* Allocate segment table. On error, destroy the table and set errno.
*
* Returns 0 on success
*/
static int
alloc_segs(hashp, nsegs)
HTAB *hashp;
int nsegs;
{
register int i;
register SEGMENT store;
int save_errno;
if ((hashp->dir =
(SEGMENT *)calloc(hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
save_errno = errno;
(void)hdestroy(hashp);
errno = save_errno;
return (-1);
}
/* Allocate segments */
if ((store =
(SEGMENT)calloc(nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
save_errno = errno;
(void)hdestroy(hashp);
errno = save_errno;
return (-1);
}
for (i = 0; i < nsegs; i++, hashp->nsegs++)
hashp->dir[i] = &store[i << hashp->SSHIFT];
return (0);
}
#if BYTE_ORDER == LITTLE_ENDIAN
/*
* Hashp->hdr needs to be byteswapped.
*/
static void
swap_header_copy(srcp, destp)
HASHHDR *srcp, *destp;
{
int i;
P_32_COPY(srcp->magic, destp->magic);
P_32_COPY(srcp->version, destp->version);
P_32_COPY(srcp->lorder, destp->lorder);
P_32_COPY(srcp->bsize, destp->bsize);
P_32_COPY(srcp->bshift, destp->bshift);
P_32_COPY(srcp->dsize, destp->dsize);
P_32_COPY(srcp->ssize, destp->ssize);
P_32_COPY(srcp->sshift, destp->sshift);
P_32_COPY(srcp->ovfl_point, destp->ovfl_point);
P_32_COPY(srcp->last_freed, destp->last_freed);
P_32_COPY(srcp->max_bucket, destp->max_bucket);
P_32_COPY(srcp->high_mask, destp->high_mask);
P_32_COPY(srcp->low_mask, destp->low_mask);
P_32_COPY(srcp->ffactor, destp->ffactor);
P_32_COPY(srcp->nkeys, destp->nkeys);
P_32_COPY(srcp->hdrpages, destp->hdrpages);
P_32_COPY(srcp->h_charkey, destp->h_charkey);
for (i = 0; i < NCACHED; i++) {
P_32_COPY(srcp->spares[i], destp->spares[i]);
P_16_COPY(srcp->bitmaps[i], destp->bitmaps[i]);
}
}
static void
swap_header(hashp)
HTAB *hashp;
{
HASHHDR *hdrp;
int i;
hdrp = &hashp->hdr;
M_32_SWAP(hdrp->magic);
M_32_SWAP(hdrp->version);
M_32_SWAP(hdrp->lorder);
M_32_SWAP(hdrp->bsize);
M_32_SWAP(hdrp->bshift);
M_32_SWAP(hdrp->dsize);
M_32_SWAP(hdrp->ssize);
M_32_SWAP(hdrp->sshift);
M_32_SWAP(hdrp->ovfl_point);
M_32_SWAP(hdrp->last_freed);
M_32_SWAP(hdrp->max_bucket);
M_32_SWAP(hdrp->high_mask);
M_32_SWAP(hdrp->low_mask);
M_32_SWAP(hdrp->ffactor);
M_32_SWAP(hdrp->nkeys);
M_32_SWAP(hdrp->hdrpages);
M_32_SWAP(hdrp->h_charkey);
for (i = 0; i < NCACHED; i++) {
M_32_SWAP(hdrp->spares[i]);
M_16_SWAP(hdrp->bitmaps[i]);
}
}
#endif
+293
View File
@@ -0,0 +1,293 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)hash.h 8.3 (Berkeley) 5/31/94
*/
/* Operations */
typedef enum {
HASH_GET, HASH_PUT, HASH_PUTNEW, HASH_DELETE, HASH_FIRST, HASH_NEXT
} ACTION;
/* Buffer Management structures */
typedef struct _bufhead BUFHEAD;
struct _bufhead {
BUFHEAD *prev; /* LRU links */
BUFHEAD *next; /* LRU links */
BUFHEAD *ovfl; /* Overflow page buffer header */
u_int32_t addr; /* Address of this page */
char *page; /* Actual page data */
char flags;
#define BUF_MOD 0x0001
#define BUF_DISK 0x0002
#define BUF_BUCKET 0x0004
#define BUF_PIN 0x0008
};
#define IS_BUCKET(X) ((X) & BUF_BUCKET)
typedef BUFHEAD **SEGMENT;
/* Hash Table Information */
typedef struct hashhdr { /* Disk resident portion */
int magic; /* Magic NO for hash tables */
int version; /* Version ID */
u_int32_t lorder; /* Byte Order */
int bsize; /* Bucket/Page Size */
int bshift; /* Bucket shift */
int dsize; /* Directory Size */
int ssize; /* Segment Size */
int sshift; /* Segment shift */
int ovfl_point; /* Where overflow pages are being
* allocated */
int last_freed; /* Last overflow page freed */
int max_bucket; /* ID of Maximum bucket in use */
int high_mask; /* Mask to modulo into entire table */
int low_mask; /* Mask to modulo into lower half of
* table */
int ffactor; /* Fill factor */
int nkeys; /* Number of keys in hash table */
int hdrpages; /* Size of table header */
int h_charkey; /* value of hash(CHARKEY) */
#define NCACHED 32 /* number of bit maps and spare
* points */
int spares[NCACHED];/* spare pages for overflow */
u_int16_t bitmaps[NCACHED]; /* address of overflow page
* bitmaps */
} HASHHDR;
typedef struct htab { /* Memory resident data structure */
HASHHDR hdr; /* Header */
int nsegs; /* Number of allocated segments */
int exsegs; /* Number of extra allocated
* segments */
u_int32_t /* Hash function */
(*hash)__P((const void *, size_t));
int flags; /* Flag values */
int fp; /* File pointer */
char *tmp_buf; /* Temporary Buffer for BIG data */
char *tmp_key; /* Temporary Buffer for BIG keys */
BUFHEAD *cpage; /* Current page */
int cbucket; /* Current bucket */
int cndx; /* Index of next item on cpage */
int errnum; /* Error Number -- for DBM
* compatability */
int new_file; /* Indicates if fd is backing store
* or no */
int save_file; /* Indicates whether we need to flush
* file at
* exit */
u_int32_t *mapp[NCACHED]; /* Pointers to page maps */
int nmaps; /* Initial number of bitmaps */
int nbufs; /* Number of buffers left to
* allocate */
BUFHEAD bufhead; /* Header of buffer lru list */
SEGMENT *dir; /* Hash Bucket directory */
} HTAB;
/*
* Constants
*/
#define MAX_BSIZE 65536 /* 2^16 */
#define MIN_BUFFERS 6
#define MINHDRSIZE 512
#define DEF_BUFSIZE 65536 /* 64 K */
#define DEF_BUCKET_SIZE 4096
#define DEF_BUCKET_SHIFT 12 /* log2(BUCKET) */
#define DEF_SEGSIZE 256
#define DEF_SEGSIZE_SHIFT 8 /* log2(SEGSIZE) */
#define DEF_DIRSIZE 256
#define DEF_FFACTOR 65536
#define MIN_FFACTOR 4
#define SPLTMAX 8
#define CHARKEY "%$sniglet^&"
#define NUMKEY 1038583
#define BYTE_SHIFT 3
#define INT_TO_BYTE 2
#define INT_BYTE_SHIFT 5
#define ALL_SET ((u_int32_t)0xFFFFFFFF)
#define ALL_CLEAR 0
#define PTROF(X) ((BUFHEAD *)((ptrdiff_t)(X)&~0x3))
#define ISMOD(X) ((u_int32_t)(ptrdiff_t)(X)&0x1)
#define DOMOD(X) ((X) = (char *)((ptrdiff_t)(X)|0x1))
#define ISDISK(X) ((u_int32_t)(ptrdiff_t)(X)&0x2)
#define DODISK(X) ((X) = (char *)((ptrdiff_t)(X)|0x2))
#define BITS_PER_MAP 32
/* Given the address of the beginning of a big map, clear/set the nth bit */
#define CLRBIT(A, N) ((A)[(N)/BITS_PER_MAP] &= ~(1<<((N)%BITS_PER_MAP)))
#define SETBIT(A, N) ((A)[(N)/BITS_PER_MAP] |= (1<<((N)%BITS_PER_MAP)))
#define ISSET(A, N) ((A)[(N)/BITS_PER_MAP] & (1<<((N)%BITS_PER_MAP)))
/* Overflow management */
/*
* Overflow page numbers are allocated per split point. At each doubling of
* the table, we can allocate extra pages. So, an overflow page number has
* the top 5 bits indicate which split point and the lower 11 bits indicate
* which page at that split point is indicated (pages within split points are
* numberered starting with 1).
*/
#define SPLITSHIFT 11
#define SPLITMASK 0x7FF
#define SPLITNUM(N) (((u_int32_t)(N)) >> SPLITSHIFT)
#define OPAGENUM(N) ((N) & SPLITMASK)
#define OADDR_OF(S,O) ((u_int32_t)((u_int32_t)(S) << SPLITSHIFT) + (O))
#define BUCKET_TO_PAGE(B) \
(B) + hashp->HDRPAGES + ((B) ? hashp->SPARES[__log2((B)+1)-1] : 0)
#define OADDR_TO_PAGE(B) \
BUCKET_TO_PAGE ( (1 << SPLITNUM((B))) -1 ) + OPAGENUM((B));
/*
* page.h contains a detailed description of the page format.
*
* Normally, keys and data are accessed from offset tables in the top of
* each page which point to the beginning of the key and data. There are
* four flag values which may be stored in these offset tables which indicate
* the following:
*
*
* OVFLPAGE Rather than a key data pair, this pair contains
* the address of an overflow page. The format of
* the pair is:
* OVERFLOW_PAGE_NUMBER OVFLPAGE
*
* PARTIAL_KEY This must be the first key/data pair on a page
* and implies that page contains only a partial key.
* That is, the key is too big to fit on a single page
* so it starts on this page and continues on the next.
* The format of the page is:
* KEY_OFF PARTIAL_KEY OVFL_PAGENO OVFLPAGE
*
* KEY_OFF -- offset of the beginning of the key
* PARTIAL_KEY -- 1
* OVFL_PAGENO - page number of the next overflow page
* OVFLPAGE -- 0
*
* FULL_KEY This must be the first key/data pair on the page. It
* is used in two cases.
*
* Case 1:
* There is a complete key on the page but no data
* (because it wouldn't fit). The next page contains
* the data.
*
* Page format it:
* KEY_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
*
* KEY_OFF -- offset of the beginning of the key
* FULL_KEY -- 2
* OVFL_PAGENO - page number of the next overflow page
* OVFLPAGE -- 0
*
* Case 2:
* This page contains no key, but part of a large
* data field, which is continued on the next page.
*
* Page format it:
* DATA_OFF FULL_KEY OVFL_PAGENO OVFL_PAGE
*
* KEY_OFF -- offset of the beginning of the data on
* this page
* FULL_KEY -- 2
* OVFL_PAGENO - page number of the next overflow page
* OVFLPAGE -- 0
*
* FULL_KEY_DATA
* This must be the first key/data pair on the page.
* There are two cases:
*
* Case 1:
* This page contains a key and the beginning of the
* data field, but the data field is continued on the
* next page.
*
* Page format is:
* KEY_OFF FULL_KEY_DATA OVFL_PAGENO DATA_OFF
*
* KEY_OFF -- offset of the beginning of the key
* FULL_KEY_DATA -- 3
* OVFL_PAGENO - page number of the next overflow page
* DATA_OFF -- offset of the beginning of the data
*
* Case 2:
* This page contains the last page of a big data pair.
* There is no key, only the tail end of the data
* on this page.
*
* Page format is:
* DATA_OFF FULL_KEY_DATA <OVFL_PAGENO> <OVFLPAGE>
*
* DATA_OFF -- offset of the beginning of the data on
* this page
* FULL_KEY_DATA -- 3
* OVFL_PAGENO - page number of the next overflow page
* OVFLPAGE -- 0
*
* OVFL_PAGENO and OVFLPAGE are optional (they are
* not present if there is no next page).
*/
#define OVFLPAGE 0
#define PARTIAL_KEY 1
#define FULL_KEY 2
#define FULL_KEY_DATA 3
#define REAL_KEY 4
/* Short hands for accessing structure */
#define BSIZE hdr.bsize
#define BSHIFT hdr.bshift
#define DSIZE hdr.dsize
#define SGSIZE hdr.ssize
#define SSHIFT hdr.sshift
#define LORDER hdr.lorder
#define OVFL_POINT hdr.ovfl_point
#define LAST_FREED hdr.last_freed
#define MAX_BUCKET hdr.max_bucket
#define FFACTOR hdr.ffactor
#define HIGH_MASK hdr.high_mask
#define LOW_MASK hdr.low_mask
#define NKEYS hdr.nkeys
#define HDRPAGES hdr.hdrpages
#define SPARES hdr.spares
#define BITMAPS hdr.bitmaps
#define VERSION hdr.version
#define MAGIC hdr.magic
#define NEXT_FREE hdr.next_free
#define H_CHARKEY hdr.h_charkey
+667
View File
@@ -0,0 +1,667 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash_bigkey.c 8.3 (Berkeley) 5/31/94";
#endif /* LIBC_SCCS and not lint */
/*
* PACKAGE: hash
* DESCRIPTION:
* Big key/data handling for the hashing package.
*
* ROUTINES:
* External
* __big_keydata
* __big_split
* __big_insert
* __big_return
* __big_delete
* __find_last_page
* Internal
* collect_key
* collect_data
*/
#include <sys/param.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef DEBUG
#include <assert.h>
#endif
#include <db.h>
#include "hash.h"
#include "page.h"
#include "extern.h"
static int collect_key __P((HTAB *, BUFHEAD *, int, DBT *, int));
static int collect_data __P((HTAB *, BUFHEAD *, int, int));
/*
* Big_insert
*
* You need to do an insert and the key/data pair is too big
*
* Returns:
* 0 ==> OK
*-1 ==> ERROR
*/
extern int
__big_insert(hashp, bufp, key, val)
HTAB *hashp;
BUFHEAD *bufp;
const DBT *key, *val;
{
register u_int16_t *p;
int key_size, n, val_size;
u_int16_t space, move_bytes, off;
char *cp, *key_data, *val_data;
cp = bufp->page; /* Character pointer of p. */
p = (u_int16_t *)cp;
key_data = (char *)key->data;
key_size = key->size;
val_data = (char *)val->data;
val_size = val->size;
/* First move the Key */
for (space = FREESPACE(p) - BIGOVERHEAD; key_size;
space = FREESPACE(p) - BIGOVERHEAD) {
move_bytes = MIN(space, key_size);
off = OFFSET(p) - move_bytes;
memmove(cp + off, key_data, move_bytes);
key_size -= move_bytes;
key_data += move_bytes;
n = p[0];
p[++n] = off;
p[0] = ++n;
FREESPACE(p) = off - PAGE_META(n);
OFFSET(p) = off;
p[n] = PARTIAL_KEY;
bufp = __add_ovflpage(hashp, bufp);
if (!bufp)
return (-1);
n = p[0];
if (!key_size)
if (FREESPACE(p)) {
move_bytes = MIN(FREESPACE(p), val_size);
off = OFFSET(p) - move_bytes;
p[n] = off;
memmove(cp + off, val_data, move_bytes);
val_data += move_bytes;
val_size -= move_bytes;
p[n - 2] = FULL_KEY_DATA;
FREESPACE(p) = FREESPACE(p) - move_bytes;
OFFSET(p) = off;
} else
p[n - 2] = FULL_KEY;
p = (u_int16_t *)bufp->page;
cp = bufp->page;
bufp->flags |= BUF_MOD;
}
/* Now move the data */
for (space = FREESPACE(p) - BIGOVERHEAD; val_size;
space = FREESPACE(p) - BIGOVERHEAD) {
move_bytes = MIN(space, val_size);
/*
* Here's the hack to make sure that if the data ends on the
* same page as the key ends, FREESPACE is at least one.
*/
if (space == val_size && val_size == val->size)
move_bytes--;
off = OFFSET(p) - move_bytes;
memmove(cp + off, val_data, move_bytes);
val_size -= move_bytes;
val_data += move_bytes;
n = p[0];
p[++n] = off;
p[0] = ++n;
FREESPACE(p) = off - PAGE_META(n);
OFFSET(p) = off;
if (val_size) {
p[n] = FULL_KEY;
bufp = __add_ovflpage(hashp, bufp);
if (!bufp)
return (-1);
cp = bufp->page;
p = (u_int16_t *)cp;
} else
p[n] = FULL_KEY_DATA;
bufp->flags |= BUF_MOD;
}
return (0);
}
/*
* Called when bufp's page contains a partial key (index should be 1)
*
* All pages in the big key/data pair except bufp are freed. We cannot
* free bufp because the page pointing to it is lost and we can't get rid
* of its pointer.
*
* Returns:
* 0 => OK
*-1 => ERROR
*/
extern int
__big_delete(hashp, bufp)
HTAB *hashp;
BUFHEAD *bufp;
{
register BUFHEAD *last_bfp, *rbufp;
u_int16_t *bp, pageno;
int key_done, n;
rbufp = bufp;
last_bfp = NULL;
bp = (u_int16_t *)bufp->page;
pageno = 0;
key_done = 0;
while (!key_done || (bp[2] != FULL_KEY_DATA)) {
if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA)
key_done = 1;
/*
* If there is freespace left on a FULL_KEY_DATA page, then
* the data is short and fits entirely on this page, and this
* is the last page.
*/
if (bp[2] == FULL_KEY_DATA && FREESPACE(bp))
break;
pageno = bp[bp[0] - 1];
rbufp->flags |= BUF_MOD;
rbufp = __get_buf(hashp, pageno, rbufp, 0);
if (last_bfp)
__free_ovflpage(hashp, last_bfp);
last_bfp = rbufp;
if (!rbufp)
return (-1); /* Error. */
bp = (u_int16_t *)rbufp->page;
}
/*
* If we get here then rbufp points to the last page of the big
* key/data pair. Bufp points to the first one -- it should now be
* empty pointing to the next page after this pair. Can't free it
* because we don't have the page pointing to it.
*/
/* This is information from the last page of the pair. */
n = bp[0];
pageno = bp[n - 1];
/* Now, bp is the first page of the pair. */
bp = (u_int16_t *)bufp->page;
if (n > 2) {
/* There is an overflow page. */
bp[1] = pageno;
bp[2] = OVFLPAGE;
bufp->ovfl = rbufp->ovfl;
} else
/* This is the last page. */
bufp->ovfl = NULL;
n -= 2;
bp[0] = n;
FREESPACE(bp) = hashp->BSIZE - PAGE_META(n);
OFFSET(bp) = hashp->BSIZE - 1;
bufp->flags |= BUF_MOD;
if (rbufp)
__free_ovflpage(hashp, rbufp);
if (last_bfp != rbufp)
__free_ovflpage(hashp, last_bfp);
hashp->NKEYS--;
return (0);
}
/*
* Returns:
* 0 = key not found
* -1 = get next overflow page
* -2 means key not found and this is big key/data
* -3 error
*/
extern int
__find_bigpair(hashp, bufp, ndx, key, size)
HTAB *hashp;
BUFHEAD *bufp;
int ndx;
char *key;
int size;
{
register u_int16_t *bp;
register char *p;
int ksize;
u_int16_t bytes;
char *kkey;
bp = (u_int16_t *)bufp->page;
p = bufp->page;
ksize = size;
kkey = key;
for (bytes = hashp->BSIZE - bp[ndx];
bytes <= size && bp[ndx + 1] == PARTIAL_KEY;
bytes = hashp->BSIZE - bp[ndx]) {
if (memcmp(p + bp[ndx], kkey, bytes))
return (-2);
kkey += bytes;
ksize -= bytes;
bufp = __get_buf(hashp, bp[ndx + 2], bufp, 0);
if (!bufp)
return (-3);
p = bufp->page;
bp = (u_int16_t *)p;
ndx = 1;
}
if (bytes != ksize || memcmp(p + bp[ndx], kkey, bytes)) {
#ifdef HASH_STATISTICS
++hash_collisions;
#endif
return (-2);
} else
return (ndx);
}
/*
* Given the buffer pointer of the first overflow page of a big pair,
* find the end of the big pair
*
* This will set bpp to the buffer header of the last page of the big pair.
* It will return the pageno of the overflow page following the last page
* of the pair; 0 if there isn't any (i.e. big pair is the last key in the
* bucket)
*/
extern u_int16_t
__find_last_page(hashp, bpp)
HTAB *hashp;
BUFHEAD **bpp;
{
BUFHEAD *bufp;
u_int16_t *bp, pageno;
int n;
bufp = *bpp;
bp = (u_int16_t *)bufp->page;
for (;;) {
n = bp[0];
/*
* This is the last page if: the tag is FULL_KEY_DATA and
* either only 2 entries OVFLPAGE marker is explicit there
* is freespace on the page.
*/
if (bp[2] == FULL_KEY_DATA &&
((n == 2) || (bp[n] == OVFLPAGE) || (FREESPACE(bp))))
break;
pageno = bp[n - 1];
bufp = __get_buf(hashp, pageno, bufp, 0);
if (!bufp)
return (0); /* Need to indicate an error! */
bp = (u_int16_t *)bufp->page;
}
*bpp = bufp;
if (bp[0] > 2)
return (bp[3]);
else
return (0);
}
/*
* Return the data for the key/data pair that begins on this page at this
* index (index should always be 1).
*/
extern int
__big_return(hashp, bufp, ndx, val, set_current)
HTAB *hashp;
BUFHEAD *bufp;
int ndx;
DBT *val;
int set_current;
{
BUFHEAD *save_p;
u_int16_t *bp, len, off, save_addr;
char *tp;
bp = (u_int16_t *)bufp->page;
while (bp[ndx + 1] == PARTIAL_KEY) {
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!bufp)
return (-1);
bp = (u_int16_t *)bufp->page;
ndx = 1;
}
if (bp[ndx + 1] == FULL_KEY) {
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!bufp)
return (-1);
bp = (u_int16_t *)bufp->page;
save_p = bufp;
save_addr = save_p->addr;
off = bp[1];
len = 0;
} else
if (!FREESPACE(bp)) {
/*
* This is a hack. We can't distinguish between
* FULL_KEY_DATA that contains complete data or
* incomplete data, so we require that if the data
* is complete, there is at least 1 byte of free
* space left.
*/
off = bp[bp[0]];
len = bp[1] - off;
save_p = bufp;
save_addr = bufp->addr;
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!bufp)
return (-1);
bp = (u_int16_t *)bufp->page;
} else {
/* The data is all on one page. */
tp = (char *)bp;
off = bp[bp[0]];
val->data = (u_char *)tp + off;
val->size = bp[1] - off;
if (set_current) {
if (bp[0] == 2) { /* No more buckets in
* chain */
hashp->cpage = NULL;
hashp->cbucket++;
hashp->cndx = 1;
} else {
hashp->cpage = __get_buf(hashp,
bp[bp[0] - 1], bufp, 0);
if (!hashp->cpage)
return (-1);
hashp->cndx = 1;
if (!((u_int16_t *)
hashp->cpage->page)[0]) {
hashp->cbucket++;
hashp->cpage = NULL;
}
}
}
return (0);
}
val->size = collect_data(hashp, bufp, (int)len, set_current);
if (val->size == -1)
return (-1);
if (save_p->addr != save_addr) {
/* We are pretty short on buffers. */
errno = EINVAL; /* OUT OF BUFFERS */
return (-1);
}
memmove(hashp->tmp_buf, (save_p->page) + off, len);
val->data = (u_char *)hashp->tmp_buf;
return (0);
}
/*
* Count how big the total datasize is by recursing through the pages. Then
* allocate a buffer and copy the data as you recurse up.
*/
static int
collect_data(hashp, bufp, len, set)
HTAB *hashp;
BUFHEAD *bufp;
int len, set;
{
register u_int16_t *bp;
register char *p;
BUFHEAD *xbp;
u_int16_t save_addr;
int mylen, totlen;
p = bufp->page;
bp = (u_int16_t *)p;
mylen = hashp->BSIZE - bp[1];
save_addr = bufp->addr;
if (bp[2] == FULL_KEY_DATA) { /* End of Data */
totlen = len + mylen;
if (hashp->tmp_buf)
free(hashp->tmp_buf);
if ((hashp->tmp_buf = (char *)malloc(totlen)) == NULL)
return (-1);
if (set) {
hashp->cndx = 1;
if (bp[0] == 2) { /* No more buckets in chain */
hashp->cpage = NULL;
hashp->cbucket++;
} else {
hashp->cpage =
__get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!hashp->cpage)
return (-1);
else if (!((u_int16_t *)hashp->cpage->page)[0]) {
hashp->cbucket++;
hashp->cpage = NULL;
}
}
}
} else {
xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!xbp || ((totlen =
collect_data(hashp, xbp, len + mylen, set)) < 1))
return (-1);
}
if (bufp->addr != save_addr) {
errno = EINVAL; /* Out of buffers. */
return (-1);
}
memmove(&hashp->tmp_buf[len], (bufp->page) + bp[1], mylen);
return (totlen);
}
/*
* Fill in the key and data for this big pair.
*/
extern int
__big_keydata(hashp, bufp, key, val, set)
HTAB *hashp;
BUFHEAD *bufp;
DBT *key, *val;
int set;
{
key->size = collect_key(hashp, bufp, 0, val, set);
if (key->size == -1)
return (-1);
key->data = (u_char *)hashp->tmp_key;
return (0);
}
/*
* Count how big the total key size is by recursing through the pages. Then
* collect the data, allocate a buffer and copy the key as you recurse up.
*/
static int
collect_key(hashp, bufp, len, val, set)
HTAB *hashp;
BUFHEAD *bufp;
int len;
DBT *val;
int set;
{
BUFHEAD *xbp;
char *p;
int mylen, totlen;
u_int16_t *bp, save_addr;
p = bufp->page;
bp = (u_int16_t *)p;
mylen = hashp->BSIZE - bp[1];
save_addr = bufp->addr;
totlen = len + mylen;
if (bp[2] == FULL_KEY || bp[2] == FULL_KEY_DATA) { /* End of Key. */
if (hashp->tmp_key != NULL)
free(hashp->tmp_key);
if ((hashp->tmp_key = (char *)malloc(totlen)) == NULL)
return (-1);
if (__big_return(hashp, bufp, 1, val, set))
return (-1);
} else {
xbp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!xbp || ((totlen =
collect_key(hashp, xbp, totlen, val, set)) < 1))
return (-1);
}
if (bufp->addr != save_addr) {
errno = EINVAL; /* MIS -- OUT OF BUFFERS */
return (-1);
}
memmove(&hashp->tmp_key[len], (bufp->page) + bp[1], mylen);
return (totlen);
}
/*
* Returns:
* 0 => OK
* -1 => error
*/
extern int
__big_split(hashp, op, np, big_keyp, addr, obucket, ret)
HTAB *hashp;
BUFHEAD *op; /* Pointer to where to put keys that go in old bucket */
BUFHEAD *np; /* Pointer to new bucket page */
/* Pointer to first page containing the big key/data */
BUFHEAD *big_keyp;
int addr; /* Address of big_keyp */
u_int32_t obucket;/* Old Bucket */
SPLIT_RETURN *ret;
{
register BUFHEAD *tmpp;
register u_int16_t *tp;
BUFHEAD *bp;
DBT key, val;
u_int32_t change;
u_int16_t free_space, n, off;
bp = big_keyp;
/* Now figure out where the big key/data goes */
if (__big_keydata(hashp, big_keyp, &key, &val, 0))
return (-1);
change = (__call_hash(hashp, key.data, key.size) != obucket);
if (ret->next_addr = __find_last_page(hashp, &big_keyp)) {
if (!(ret->nextp =
__get_buf(hashp, ret->next_addr, big_keyp, 0)))
return (-1);;
} else
ret->nextp = NULL;
/* Now make one of np/op point to the big key/data pair */
#ifdef DEBUG
assert(np->ovfl == NULL);
#endif
if (change)
tmpp = np;
else
tmpp = op;
tmpp->flags |= BUF_MOD;
#ifdef DEBUG1
(void)fprintf(stderr,
"BIG_SPLIT: %d->ovfl was %d is now %d\n", tmpp->addr,
(tmpp->ovfl ? tmpp->ovfl->addr : 0), (bp ? bp->addr : 0));
#endif
tmpp->ovfl = bp; /* one of op/np point to big_keyp */
tp = (u_int16_t *)tmpp->page;
#ifdef DEBUG
assert(FREESPACE(tp) >= OVFLSIZE);
#endif
n = tp[0];
off = OFFSET(tp);
free_space = FREESPACE(tp);
tp[++n] = (u_int16_t)addr;
tp[++n] = OVFLPAGE;
tp[0] = n;
OFFSET(tp) = off;
FREESPACE(tp) = free_space - OVFLSIZE;
/*
* Finally, set the new and old return values. BIG_KEYP contains a
* pointer to the last page of the big key_data pair. Make sure that
* big_keyp has no following page (2 elements) or create an empty
* following page.
*/
ret->newp = np;
ret->oldp = op;
tp = (u_int16_t *)big_keyp->page;
big_keyp->flags |= BUF_MOD;
if (tp[0] > 2) {
/*
* There may be either one or two offsets on this page. If
* there is one, then the overflow page is linked on normally
* and tp[4] is OVFLPAGE. If there are two, tp[4] contains
* the second offset and needs to get stuffed in after the
* next overflow page is added.
*/
n = tp[4];
free_space = FREESPACE(tp);
off = OFFSET(tp);
tp[0] -= 2;
FREESPACE(tp) = free_space + OVFLSIZE;
OFFSET(tp) = off;
tmpp = __add_ovflpage(hashp, big_keyp);
if (!tmpp)
return (-1);
tp[4] = n;
} else
tmpp = big_keyp;
if (change)
ret->newp = tmpp;
else
ret->oldp = tmpp;
return (0);
}
+355
View File
@@ -0,0 +1,355 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash_buf.c 8.5 (Berkeley) 7/15/94";
#endif /* LIBC_SCCS and not lint */
/*
* PACKAGE: hash
*
* DESCRIPTION:
* Contains buffer management
*
* ROUTINES:
* External
* __buf_init
* __get_buf
* __buf_free
* __reclaim_buf
* Internal
* newbuf
*/
#include <sys/param.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef DEBUG
#include <assert.h>
#endif
#include <db.h>
#include "hash.h"
#include "page.h"
#include "extern.h"
static BUFHEAD *newbuf __P((HTAB *, u_int32_t, BUFHEAD *));
/* Unlink B from its place in the lru */
#define BUF_REMOVE(B) { \
(B)->prev->next = (B)->next; \
(B)->next->prev = (B)->prev; \
}
/* Insert B after P */
#define BUF_INSERT(B, P) { \
(B)->next = (P)->next; \
(B)->prev = (P); \
(P)->next = (B); \
(B)->next->prev = (B); \
}
#define MRU hashp->bufhead.next
#define LRU hashp->bufhead.prev
#define MRU_INSERT(B) BUF_INSERT((B), &hashp->bufhead)
#define LRU_INSERT(B) BUF_INSERT((B), LRU)
/*
* We are looking for a buffer with address "addr". If prev_bp is NULL, then
* address is a bucket index. If prev_bp is not NULL, then it points to the
* page previous to an overflow page that we are trying to find.
*
* CAVEAT: The buffer header accessed via prev_bp's ovfl field may no longer
* be valid. Therefore, you must always verify that its address matches the
* address you are seeking.
*/
extern BUFHEAD *
__get_buf(hashp, addr, prev_bp, newpage)
HTAB *hashp;
u_int32_t addr;
BUFHEAD *prev_bp;
int newpage; /* If prev_bp set, indicates a new overflow page. */
{
register BUFHEAD *bp;
register u_int32_t is_disk_mask;
register int is_disk, segment_ndx;
SEGMENT segp;
is_disk = 0;
is_disk_mask = 0;
if (prev_bp) {
bp = prev_bp->ovfl;
if (!bp || (bp->addr != addr))
bp = NULL;
if (!newpage)
is_disk = BUF_DISK;
} else {
/* Grab buffer out of directory */
segment_ndx = addr & (hashp->SGSIZE - 1);
/* valid segment ensured by __call_hash() */
segp = hashp->dir[addr >> hashp->SSHIFT];
#ifdef DEBUG
assert(segp != NULL);
#endif
bp = PTROF(segp[segment_ndx]);
is_disk_mask = ISDISK(segp[segment_ndx]);
is_disk = is_disk_mask || !hashp->new_file;
}
if (!bp) {
bp = newbuf(hashp, addr, prev_bp);
if (!bp ||
__get_page(hashp, bp->page, addr, !prev_bp, is_disk, 0))
return (NULL);
if (!prev_bp)
segp[segment_ndx] =
(BUFHEAD *)((ptrdiff_t)bp | is_disk_mask);
} else {
BUF_REMOVE(bp);
MRU_INSERT(bp);
}
return (bp);
}
/*
* We need a buffer for this page. Either allocate one, or evict a resident
* one (if we have as many buffers as we're allowed) and put this one in.
*
* If newbuf finds an error (returning NULL), it also sets errno.
*/
static BUFHEAD *
newbuf(hashp, addr, prev_bp)
HTAB *hashp;
u_int32_t addr;
BUFHEAD *prev_bp;
{
register BUFHEAD *bp; /* The buffer we're going to use */
register BUFHEAD *xbp; /* Temp pointer */
register BUFHEAD *next_xbp;
SEGMENT segp;
int segment_ndx;
u_int16_t oaddr, *shortp;
oaddr = 0;
bp = LRU;
/*
* If LRU buffer is pinned, the buffer pool is too small. We need to
* allocate more buffers.
*/
if (hashp->nbufs || (bp->flags & BUF_PIN)) {
/* Allocate a new one */
if ((bp = (BUFHEAD *)malloc(sizeof(BUFHEAD))) == NULL)
return (NULL);
#ifdef PURIFY
memset(bp, 0xff, sizeof(BUFHEAD));
#endif
if ((bp->page = (char *)malloc(hashp->BSIZE)) == NULL) {
free(bp);
return (NULL);
}
#ifdef PURIFY
memset(bp->page, 0xff, hashp->BSIZE);
#endif
if (hashp->nbufs)
hashp->nbufs--;
} else {
/* Kick someone out */
BUF_REMOVE(bp);
/*
* If this is an overflow page with addr 0, it's already been
* flushed back in an overflow chain and initialized.
*/
if ((bp->addr != 0) || (bp->flags & BUF_BUCKET)) {
/*
* Set oaddr before __put_page so that you get it
* before bytes are swapped.
*/
shortp = (u_int16_t *)bp->page;
if (shortp[0])
oaddr = shortp[shortp[0] - 1];
if ((bp->flags & BUF_MOD) && __put_page(hashp, bp->page,
bp->addr, (int)IS_BUCKET(bp->flags), 0))
return (NULL);
/*
* Update the pointer to this page (i.e. invalidate it).
*
* If this is a new file (i.e. we created it at open
* time), make sure that we mark pages which have been
* written to disk so we retrieve them from disk later,
* rather than allocating new pages.
*/
if (IS_BUCKET(bp->flags)) {
segment_ndx = bp->addr & (hashp->SGSIZE - 1);
segp = hashp->dir[bp->addr >> hashp->SSHIFT];
#ifdef DEBUG
assert(segp != NULL);
#endif
if (hashp->new_file &&
((bp->flags & BUF_MOD) ||
ISDISK(segp[segment_ndx])))
segp[segment_ndx] = (BUFHEAD *)BUF_DISK;
else
segp[segment_ndx] = NULL;
}
/*
* Since overflow pages can only be access by means of
* their bucket, free overflow pages associated with
* this bucket.
*/
for (xbp = bp; xbp->ovfl;) {
next_xbp = xbp->ovfl;
xbp->ovfl = 0;
xbp = next_xbp;
/* Check that ovfl pointer is up date. */
if (IS_BUCKET(xbp->flags) ||
(oaddr != xbp->addr))
break;
shortp = (u_int16_t *)xbp->page;
if (shortp[0])
/* set before __put_page */
oaddr = shortp[shortp[0] - 1];
if ((xbp->flags & BUF_MOD) && __put_page(hashp,
xbp->page, xbp->addr, 0, 0))
return (NULL);
xbp->addr = 0;
xbp->flags = 0;
BUF_REMOVE(xbp);
LRU_INSERT(xbp);
}
}
}
/* Now assign this buffer */
bp->addr = addr;
#ifdef DEBUG1
(void)fprintf(stderr, "NEWBUF1: %d->ovfl was %d is now %d\n",
bp->addr, (bp->ovfl ? bp->ovfl->addr : 0), 0);
#endif
bp->ovfl = NULL;
if (prev_bp) {
/*
* If prev_bp is set, this is an overflow page, hook it in to
* the buffer overflow links.
*/
#ifdef DEBUG1
(void)fprintf(stderr, "NEWBUF2: %d->ovfl was %d is now %d\n",
prev_bp->addr, (prev_bp->ovfl ? bp->ovfl->addr : 0),
(bp ? bp->addr : 0));
#endif
prev_bp->ovfl = bp;
bp->flags = 0;
} else
bp->flags = BUF_BUCKET;
MRU_INSERT(bp);
return (bp);
}
extern void
__buf_init(hashp, nbytes)
HTAB *hashp;
int nbytes;
{
BUFHEAD *bfp;
int npages;
bfp = &(hashp->bufhead);
npages = (nbytes + hashp->BSIZE - 1) >> hashp->BSHIFT;
npages = MAX(npages, MIN_BUFFERS);
hashp->nbufs = npages;
bfp->next = bfp;
bfp->prev = bfp;
/*
* This space is calloc'd so these are already null.
*
* bfp->ovfl = NULL;
* bfp->flags = 0;
* bfp->page = NULL;
* bfp->addr = 0;
*/
}
extern int
__buf_free(hashp, do_free, to_disk)
HTAB *hashp;
int do_free, to_disk;
{
BUFHEAD *bp;
/* Need to make sure that buffer manager has been initialized */
if (!LRU)
return (0);
for (bp = LRU; bp != &hashp->bufhead;) {
/* Check that the buffer is valid */
if (bp->addr || IS_BUCKET(bp->flags)) {
if (to_disk && (bp->flags & BUF_MOD) &&
__put_page(hashp, bp->page,
bp->addr, IS_BUCKET(bp->flags), 0))
return (-1);
}
/* Check if we are freeing stuff */
if (do_free) {
if (bp->page)
free(bp->page);
BUF_REMOVE(bp);
free(bp);
bp = LRU;
} else
bp = bp->prev;
}
return (0);
}
extern void
__reclaim_buf(hashp, bp)
HTAB *hashp;
BUFHEAD *bp;
{
bp->ovfl = 0;
bp->addr = 0;
bp->flags = 0;
BUF_REMOVE(bp);
LRU_INSERT(bp);
}
+212
View File
@@ -0,0 +1,212 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash_func.c 8.2 (Berkeley) 2/21/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <db.h>
#include "hash.h"
#include "page.h"
#include "extern.h"
static u_int32_t hash1 __P((const void *, size_t));
static u_int32_t hash2 __P((const void *, size_t));
static u_int32_t hash3 __P((const void *, size_t));
static u_int32_t hash4 __P((const void *, size_t));
/* Global default hash function */
u_int32_t (*__default_hash) __P((const void *, size_t)) = hash4;
/*
* HASH FUNCTIONS
*
* Assume that we've already split the bucket to which this key hashes,
* calculate that bucket, and check that in fact we did already split it.
*
* This came from ejb's hsearch.
*/
#define PRIME1 37
#define PRIME2 1048583
static u_int32_t
hash1(keyarg, len)
const void *keyarg;
register size_t len;
{
register const u_char *key;
register u_int32_t h;
/* Convert string to integer */
for (key = keyarg, h = 0; len--;)
h = h * PRIME1 ^ (*key++ - ' ');
h %= PRIME2;
return (h);
}
/*
* Phong's linear congruential hash
*/
#define dcharhash(h, c) ((h) = 0x63c63cd9*(h) + 0x9c39c33d + (c))
static u_int32_t
hash2(keyarg, len)
const void *keyarg;
size_t len;
{
register const u_char *e, *key;
register u_int32_t h;
register u_char c;
key = keyarg;
e = key + len;
for (h = 0; key != e;) {
c = *key++;
if (!c && key > e)
break;
dcharhash(h, c);
}
return (h);
}
/*
* This is INCREDIBLY ugly, but fast. We break the string up into 8 byte
* units. On the first time through the loop we get the "leftover bytes"
* (strlen % 8). On every other iteration, we perform 8 HASHC's so we handle
* all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If
* this routine is heavily used enough, it's worth the ugly coding.
*
* OZ's original sdbm hash
*/
static u_int32_t
hash3(keyarg, len)
const void *keyarg;
register size_t len;
{
register const u_char *key;
register size_t loop;
register u_int32_t h;
#define HASHC h = *key++ + 65599 * h
h = 0;
key = keyarg;
if (len > 0) {
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1)) {
case 0:
do {
HASHC;
/* FALLTHROUGH */
case 7:
HASHC;
/* FALLTHROUGH */
case 6:
HASHC;
/* FALLTHROUGH */
case 5:
HASHC;
/* FALLTHROUGH */
case 4:
HASHC;
/* FALLTHROUGH */
case 3:
HASHC;
/* FALLTHROUGH */
case 2:
HASHC;
/* FALLTHROUGH */
case 1:
HASHC;
} while (--loop);
}
}
return (h);
}
/* Hash function from Chris Torek. */
static u_int32_t
hash4(keyarg, len)
const void *keyarg;
register size_t len;
{
register const u_char *key;
register size_t loop;
register u_int32_t h;
#define HASH4a h = (h << 5) - h + *key++;
#define HASH4b h = (h << 5) + h + *key++;
#define HASH4 HASH4b
h = 0;
key = keyarg;
if (len > 0) {
loop = (len + 8 - 1) >> 3;
switch (len & (8 - 1)) {
case 0:
do {
HASH4;
/* FALLTHROUGH */
case 7:
HASH4;
/* FALLTHROUGH */
case 6:
HASH4;
/* FALLTHROUGH */
case 5:
HASH4;
/* FALLTHROUGH */
case 4:
HASH4;
/* FALLTHROUGH */
case 3:
HASH4;
/* FALLTHROUGH */
case 2:
HASH4;
/* FALLTHROUGH */
case 1:
HASH4;
} while (--loop);
}
}
return (h);
}
+56
View File
@@ -0,0 +1,56 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash_log2.c 8.2 (Berkeley) 5/31/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <db.h>
u_int32_t __log2 __P((u_int32_t));
u_int32_t
__log2(num)
u_int32_t num;
{
register u_int32_t i, limit;
limit = 1;
for (i = 0; limit < num; limit = limit << 1, i++);
return (i);
}
+944
View File
@@ -0,0 +1,944 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)hash_page.c 8.7 (Berkeley) 8/16/94";
#endif /* LIBC_SCCS and not lint */
/*
* PACKAGE: hashing
*
* DESCRIPTION:
* Page manipulation for hashing package.
*
* ROUTINES:
*
* External
* __get_page
* __add_ovflpage
* Internal
* overflow_page
* open_temp
*/
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef DEBUG
#include <assert.h>
#endif
#include <db.h>
#include "hash.h"
#include "page.h"
#include "extern.h"
static u_int32_t *fetch_bitmap __P((HTAB *, int));
static u_int32_t first_free __P((u_int32_t));
static int open_temp __P((HTAB *));
static u_int16_t overflow_page __P((HTAB *));
static void putpair __P((char *, const DBT *, const DBT *));
static void squeeze_key __P((u_int16_t *, const DBT *, const DBT *));
static int ugly_split
__P((HTAB *, u_int32_t, BUFHEAD *, BUFHEAD *, int, int));
#define PAGE_INIT(P) { \
((u_int16_t *)(P))[0] = 0; \
((u_int16_t *)(P))[1] = hashp->BSIZE - 3 * sizeof(u_int16_t); \
((u_int16_t *)(P))[2] = hashp->BSIZE; \
}
/*
* This is called AFTER we have verified that there is room on the page for
* the pair (PAIRFITS has returned true) so we go right ahead and start moving
* stuff on.
*/
static void
putpair(p, key, val)
char *p;
const DBT *key, *val;
{
register u_int16_t *bp, n, off;
bp = (u_int16_t *)p;
/* Enter the key first. */
n = bp[0];
off = OFFSET(bp) - key->size;
memmove(p + off, key->data, key->size);
bp[++n] = off;
/* Now the data. */
off -= val->size;
memmove(p + off, val->data, val->size);
bp[++n] = off;
/* Adjust page info. */
bp[0] = n;
bp[n + 1] = off - ((n + 3) * sizeof(u_int16_t));
bp[n + 2] = off;
}
/*
* Returns:
* 0 OK
* -1 error
*/
extern int
__delpair(hashp, bufp, ndx)
HTAB *hashp;
BUFHEAD *bufp;
register int ndx;
{
register u_int16_t *bp, newoff;
register int n;
u_int16_t pairlen;
bp = (u_int16_t *)bufp->page;
n = bp[0];
if (bp[ndx + 1] < REAL_KEY)
return (__big_delete(hashp, bufp));
if (ndx != 1)
newoff = bp[ndx - 1];
else
newoff = hashp->BSIZE;
pairlen = newoff - bp[ndx + 1];
if (ndx != (n - 1)) {
/* Hard Case -- need to shuffle keys */
register int i;
register char *src = bufp->page + (int)OFFSET(bp);
register char *dst = src + (int)pairlen;
memmove(dst, src, bp[ndx + 1] - OFFSET(bp));
/* Now adjust the pointers */
for (i = ndx + 2; i <= n; i += 2) {
if (bp[i + 1] == OVFLPAGE) {
bp[i - 2] = bp[i];
bp[i - 1] = bp[i + 1];
} else {
bp[i - 2] = bp[i] + pairlen;
bp[i - 1] = bp[i + 1] + pairlen;
}
}
}
/* Finally adjust the page data */
bp[n] = OFFSET(bp) + pairlen;
bp[n - 1] = bp[n + 1] + pairlen + 2 * sizeof(u_int16_t);
bp[0] = n - 2;
hashp->NKEYS--;
bufp->flags |= BUF_MOD;
return (0);
}
/*
* Returns:
* 0 ==> OK
* -1 ==> Error
*/
extern int
__split_page(hashp, obucket, nbucket)
HTAB *hashp;
u_int32_t obucket, nbucket;
{
register BUFHEAD *new_bufp, *old_bufp;
register u_int16_t *ino;
register char *np;
DBT key, val;
int n, ndx, retval;
u_int16_t copyto, diff, off, moved;
char *op;
copyto = (u_int16_t)hashp->BSIZE;
off = (u_int16_t)hashp->BSIZE;
old_bufp = __get_buf(hashp, obucket, NULL, 0);
if (old_bufp == NULL)
return (-1);
new_bufp = __get_buf(hashp, nbucket, NULL, 0);
if (new_bufp == NULL)
return (-1);
old_bufp->flags |= (BUF_MOD | BUF_PIN);
new_bufp->flags |= (BUF_MOD | BUF_PIN);
ino = (u_int16_t *)(op = old_bufp->page);
np = new_bufp->page;
moved = 0;
for (n = 1, ndx = 1; n < ino[0]; n += 2) {
if (ino[n + 1] < REAL_KEY) {
retval = ugly_split(hashp, obucket, old_bufp, new_bufp,
(int)copyto, (int)moved);
old_bufp->flags &= ~BUF_PIN;
new_bufp->flags &= ~BUF_PIN;
return (retval);
}
key.data = (u_char *)op + ino[n];
key.size = off - ino[n];
if (__call_hash(hashp, key.data, key.size) == obucket) {
/* Don't switch page */
diff = copyto - off;
if (diff) {
copyto = ino[n + 1] + diff;
memmove(op + copyto, op + ino[n + 1],
off - ino[n + 1]);
ino[ndx] = copyto + ino[n] - ino[n + 1];
ino[ndx + 1] = copyto;
} else
copyto = ino[n + 1];
ndx += 2;
} else {
/* Switch page */
val.data = (u_char *)op + ino[n + 1];
val.size = ino[n] - ino[n + 1];
putpair(np, &key, &val);
moved += 2;
}
off = ino[n + 1];
}
/* Now clean up the page */
ino[0] -= moved;
FREESPACE(ino) = copyto - sizeof(u_int16_t) * (ino[0] + 3);
OFFSET(ino) = copyto;
#ifdef DEBUG3
(void)fprintf(stderr, "split %d/%d\n",
((u_int16_t *)np)[0] / 2,
((u_int16_t *)op)[0] / 2);
#endif
/* unpin both pages */
old_bufp->flags &= ~BUF_PIN;
new_bufp->flags &= ~BUF_PIN;
return (0);
}
/*
* Called when we encounter an overflow or big key/data page during split
* handling. This is special cased since we have to begin checking whether
* the key/data pairs fit on their respective pages and because we may need
* overflow pages for both the old and new pages.
*
* The first page might be a page with regular key/data pairs in which case
* we have a regular overflow condition and just need to go on to the next
* page or it might be a big key/data pair in which case we need to fix the
* big key/data pair.
*
* Returns:
* 0 ==> success
* -1 ==> failure
*/
static int
ugly_split(hashp, obucket, old_bufp, new_bufp, copyto, moved)
HTAB *hashp;
u_int32_t obucket; /* Same as __split_page. */
BUFHEAD *old_bufp, *new_bufp;
int copyto; /* First byte on page which contains key/data values. */
int moved; /* Number of pairs moved to new page. */
{
register BUFHEAD *bufp; /* Buffer header for ino */
register u_int16_t *ino; /* Page keys come off of */
register u_int16_t *np; /* New page */
register u_int16_t *op; /* Page keys go on to if they aren't moving */
BUFHEAD *last_bfp; /* Last buf header OVFL needing to be freed */
DBT key, val;
SPLIT_RETURN ret;
u_int16_t n, off, ov_addr, scopyto;
char *cino; /* Character value of ino */
bufp = old_bufp;
ino = (u_int16_t *)old_bufp->page;
np = (u_int16_t *)new_bufp->page;
op = (u_int16_t *)old_bufp->page;
last_bfp = NULL;
scopyto = (u_int16_t)copyto; /* ANSI */
n = ino[0] - 1;
while (n < ino[0]) {
if (ino[2] < REAL_KEY && ino[2] != OVFLPAGE) {
if (__big_split(hashp, old_bufp,
new_bufp, bufp, bufp->addr, obucket, &ret))
return (-1);
old_bufp = ret.oldp;
if (!old_bufp)
return (-1);
op = (u_int16_t *)old_bufp->page;
new_bufp = ret.newp;
if (!new_bufp)
return (-1);
np = (u_int16_t *)new_bufp->page;
bufp = ret.nextp;
if (!bufp)
return (0);
cino = (char *)bufp->page;
ino = (u_int16_t *)cino;
last_bfp = ret.nextp;
} else if (ino[n + 1] == OVFLPAGE) {
ov_addr = ino[n];
/*
* Fix up the old page -- the extra 2 are the fields
* which contained the overflow information.
*/
ino[0] -= (moved + 2);
FREESPACE(ino) =
scopyto - sizeof(u_int16_t) * (ino[0] + 3);
OFFSET(ino) = scopyto;
bufp = __get_buf(hashp, ov_addr, bufp, 0);
if (!bufp)
return (-1);
ino = (u_int16_t *)bufp->page;
n = 1;
scopyto = hashp->BSIZE;
moved = 0;
if (last_bfp)
__free_ovflpage(hashp, last_bfp);
last_bfp = bufp;
}
/* Move regular sized pairs of there are any */
off = hashp->BSIZE;
for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
cino = (char *)ino;
key.data = (u_char *)cino + ino[n];
key.size = off - ino[n];
val.data = (u_char *)cino + ino[n + 1];
val.size = ino[n] - ino[n + 1];
off = ino[n + 1];
if (__call_hash(hashp, key.data, key.size) == obucket) {
/* Keep on old page */
if (PAIRFITS(op, (&key), (&val)))
putpair((char *)op, &key, &val);
else {
old_bufp =
__add_ovflpage(hashp, old_bufp);
if (!old_bufp)
return (-1);
op = (u_int16_t *)old_bufp->page;
putpair((char *)op, &key, &val);
}
old_bufp->flags |= BUF_MOD;
} else {
/* Move to new page */
if (PAIRFITS(np, (&key), (&val)))
putpair((char *)np, &key, &val);
else {
new_bufp =
__add_ovflpage(hashp, new_bufp);
if (!new_bufp)
return (-1);
np = (u_int16_t *)new_bufp->page;
putpair((char *)np, &key, &val);
}
new_bufp->flags |= BUF_MOD;
}
}
}
if (last_bfp)
__free_ovflpage(hashp, last_bfp);
return (0);
}
/*
* Add the given pair to the page
*
* Returns:
* 0 ==> OK
* 1 ==> failure
*/
extern int
__addel(hashp, bufp, key, val)
HTAB *hashp;
BUFHEAD *bufp;
const DBT *key, *val;
{
register u_int16_t *bp, *sop;
int do_expand;
bp = (u_int16_t *)bufp->page;
do_expand = 0;
while (bp[0] && (bp[2] < REAL_KEY || bp[bp[0]] < REAL_KEY))
/* Exception case */
if (bp[2] == FULL_KEY_DATA && bp[0] == 2)
/* This is the last page of a big key/data pair
and we need to add another page */
break;
else if (bp[2] < REAL_KEY && bp[bp[0]] != OVFLPAGE) {
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!bufp)
return (-1);
bp = (u_int16_t *)bufp->page;
} else
/* Try to squeeze key on this page */
if (FREESPACE(bp) > PAIRSIZE(key, val)) {
squeeze_key(bp, key, val);
return (0);
} else {
bufp = __get_buf(hashp, bp[bp[0] - 1], bufp, 0);
if (!bufp)
return (-1);
bp = (u_int16_t *)bufp->page;
}
if (PAIRFITS(bp, key, val))
putpair(bufp->page, key, val);
else {
do_expand = 1;
bufp = __add_ovflpage(hashp, bufp);
if (!bufp)
return (-1);
sop = (u_int16_t *)bufp->page;
if (PAIRFITS(sop, key, val))
putpair((char *)sop, key, val);
else
if (__big_insert(hashp, bufp, key, val))
return (-1);
}
bufp->flags |= BUF_MOD;
/*
* If the average number of keys per bucket exceeds the fill factor,
* expand the table.
*/
hashp->NKEYS++;
if (do_expand ||
(hashp->NKEYS / (hashp->MAX_BUCKET + 1) > hashp->FFACTOR))
return (__expand_table(hashp));
return (0);
}
/*
*
* Returns:
* pointer on success
* NULL on error
*/
extern BUFHEAD *
__add_ovflpage(hashp, bufp)
HTAB *hashp;
BUFHEAD *bufp;
{
register u_int16_t *sp;
u_int16_t ndx, ovfl_num;
#ifdef DEBUG1
int tmp1, tmp2;
#endif
sp = (u_int16_t *)bufp->page;
/* Check if we are dynamically determining the fill factor */
if (hashp->FFACTOR == DEF_FFACTOR) {
hashp->FFACTOR = sp[0] >> 1;
if (hashp->FFACTOR < MIN_FFACTOR)
hashp->FFACTOR = MIN_FFACTOR;
}
bufp->flags |= BUF_MOD;
ovfl_num = overflow_page(hashp);
#ifdef DEBUG1
tmp1 = bufp->addr;
tmp2 = bufp->ovfl ? bufp->ovfl->addr : 0;
#endif
if (!ovfl_num || !(bufp->ovfl = __get_buf(hashp, ovfl_num, bufp, 1)))
return (NULL);
bufp->ovfl->flags |= BUF_MOD;
#ifdef DEBUG1
(void)fprintf(stderr, "ADDOVFLPAGE: %d->ovfl was %d is now %d\n",
tmp1, tmp2, bufp->ovfl->addr);
#endif
ndx = sp[0];
/*
* Since a pair is allocated on a page only if there's room to add
* an overflow page, we know that the OVFL information will fit on
* the page.
*/
sp[ndx + 4] = OFFSET(sp);
sp[ndx + 3] = FREESPACE(sp) - OVFLSIZE;
sp[ndx + 1] = ovfl_num;
sp[ndx + 2] = OVFLPAGE;
sp[0] = ndx + 2;
#ifdef HASH_STATISTICS
hash_overflows++;
#endif
return (bufp->ovfl);
}
/*
* Returns:
* 0 indicates SUCCESS
* -1 indicates FAILURE
*/
extern int
__get_page(hashp, p, bucket, is_bucket, is_disk, is_bitmap)
HTAB *hashp;
char *p;
u_int32_t bucket;
int is_bucket, is_disk, is_bitmap;
{
register int fd, page, size;
int rsize;
u_int16_t *bp;
fd = hashp->fp;
size = hashp->BSIZE;
if ((fd == -1) || !is_disk) {
PAGE_INIT(p);
return (0);
}
if (is_bucket)
page = BUCKET_TO_PAGE(bucket);
else
page = OADDR_TO_PAGE(bucket);
if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
((rsize = read(fd, p, size)) == -1))
return (-1);
bp = (u_int16_t *)p;
if (!rsize)
bp[0] = 0; /* We hit the EOF, so initialize a new page */
else
if (rsize != size) {
errno = EFTYPE;
return (-1);
}
if (!is_bitmap && !bp[0]) {
PAGE_INIT(p);
} else
if (hashp->LORDER != BYTE_ORDER) {
register int i, max;
if (is_bitmap) {
max = hashp->BSIZE >> 2; /* divide by 4 */
for (i = 0; i < max; i++)
M_32_SWAP(((int *)p)[i]);
} else {
M_16_SWAP(bp[0]);
max = bp[0] + 2;
for (i = 1; i <= max; i++)
M_16_SWAP(bp[i]);
}
}
return (0);
}
/*
* Write page p to disk
*
* Returns:
* 0 ==> OK
* -1 ==>failure
*/
extern int
__put_page(hashp, p, bucket, is_bucket, is_bitmap)
HTAB *hashp;
char *p;
u_int32_t bucket;
int is_bucket, is_bitmap;
{
register int fd, page, size;
int wsize;
size = hashp->BSIZE;
if ((hashp->fp == -1) && open_temp(hashp))
return (-1);
fd = hashp->fp;
if (hashp->LORDER != BYTE_ORDER) {
register int i;
register int max;
if (is_bitmap) {
max = hashp->BSIZE >> 2; /* divide by 4 */
for (i = 0; i < max; i++)
M_32_SWAP(((int *)p)[i]);
} else {
max = ((u_int16_t *)p)[0] + 2;
for (i = 0; i <= max; i++)
M_16_SWAP(((u_int16_t *)p)[i]);
}
}
if (is_bucket)
page = BUCKET_TO_PAGE(bucket);
else
page = OADDR_TO_PAGE(bucket);
if ((lseek(fd, (off_t)page << hashp->BSHIFT, SEEK_SET) == -1) ||
((wsize = write(fd, p, size)) == -1))
/* Errno is set */
return (-1);
if (wsize != size) {
errno = EFTYPE;
return (-1);
}
return (0);
}
#define BYTE_MASK ((1 << INT_BYTE_SHIFT) -1)
/*
* Initialize a new bitmap page. Bitmap pages are left in memory
* once they are read in.
*/
extern int
__ibitmap(hashp, pnum, nbits, ndx)
HTAB *hashp;
int pnum, nbits, ndx;
{
u_int32_t *ip;
int clearbytes, clearints;
if ((ip = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
return (1);
hashp->nmaps++;
clearints = ((nbits - 1) >> INT_BYTE_SHIFT) + 1;
clearbytes = clearints << INT_TO_BYTE;
(void)memset((char *)ip, 0, clearbytes);
(void)memset(((char *)ip) + clearbytes, 0xFF,
hashp->BSIZE - clearbytes);
ip[clearints - 1] = ALL_SET << (nbits & BYTE_MASK);
SETBIT(ip, 0);
hashp->BITMAPS[ndx] = (u_int16_t)pnum;
hashp->mapp[ndx] = ip;
return (0);
}
static u_int32_t
first_free(map)
u_int32_t map;
{
register u_int32_t i, mask;
mask = 0x1;
for (i = 0; i < BITS_PER_MAP; i++) {
if (!(mask & map))
return (i);
mask = mask << 1;
}
return (i);
}
static u_int16_t
overflow_page(hashp)
HTAB *hashp;
{
register u_int32_t *freep;
register int max_free, offset, splitnum;
u_int16_t addr;
int bit, first_page, free_bit, free_page, i, in_use_bits, j;
#ifdef DEBUG2
int tmp1, tmp2;
#endif
splitnum = hashp->OVFL_POINT;
max_free = hashp->SPARES[splitnum];
free_page = (max_free - 1) >> (hashp->BSHIFT + BYTE_SHIFT);
free_bit = (max_free - 1) & ((hashp->BSIZE << BYTE_SHIFT) - 1);
/* Look through all the free maps to find the first free block */
first_page = hashp->LAST_FREED >>(hashp->BSHIFT + BYTE_SHIFT);
for ( i = first_page; i <= free_page; i++ ) {
if (!(freep = (u_int32_t *)hashp->mapp[i]) &&
!(freep = fetch_bitmap(hashp, i)))
return (0);
if (i == free_page)
in_use_bits = free_bit;
else
in_use_bits = (hashp->BSIZE << BYTE_SHIFT) - 1;
if (i == first_page) {
bit = hashp->LAST_FREED &
((hashp->BSIZE << BYTE_SHIFT) - 1);
j = bit / BITS_PER_MAP;
bit = bit & ~(BITS_PER_MAP - 1);
} else {
bit = 0;
j = 0;
}
for (; bit <= in_use_bits; j++, bit += BITS_PER_MAP)
if (freep[j] != ALL_SET)
goto found;
}
/* No Free Page Found */
hashp->LAST_FREED = hashp->SPARES[splitnum];
hashp->SPARES[splitnum]++;
offset = hashp->SPARES[splitnum] -
(splitnum ? hashp->SPARES[splitnum - 1] : 0);
#define OVMSG "HASH: Out of overflow pages. Increase page size\n"
if (offset > SPLITMASK) {
if (++splitnum >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
return (0);
}
hashp->OVFL_POINT = splitnum;
hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
hashp->SPARES[splitnum-1]--;
offset = 1;
}
/* Check if we need to allocate a new bitmap page */
if (free_bit == (hashp->BSIZE << BYTE_SHIFT) - 1) {
free_page++;
if (free_page >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG, sizeof(OVMSG) - 1);
return (0);
}
/*
* This is tricky. The 1 indicates that you want the new page
* allocated with 1 clear bit. Actually, you are going to
* allocate 2 pages from this map. The first is going to be
* the map page, the second is the overflow page we were
* looking for. The init_bitmap routine automatically, sets
* the first bit of itself to indicate that the bitmap itself
* is in use. We would explicitly set the second bit, but
* don't have to if we tell init_bitmap not to leave it clear
* in the first place.
*/
if (__ibitmap(hashp,
(int)OADDR_OF(splitnum, offset), 1, free_page))
return (0);
hashp->SPARES[splitnum]++;
#ifdef DEBUG2
free_bit = 2;
#endif
offset++;
if (offset > SPLITMASK) {
if (++splitnum >= NCACHED) {
(void)write(STDERR_FILENO, OVMSG,
sizeof(OVMSG) - 1);
return (0);
}
hashp->OVFL_POINT = splitnum;
hashp->SPARES[splitnum] = hashp->SPARES[splitnum-1];
hashp->SPARES[splitnum-1]--;
offset = 0;
}
} else {
/*
* Free_bit addresses the last used bit. Bump it to address
* the first available bit.
*/
free_bit++;
SETBIT(freep, free_bit);
}
/* Calculate address of the new overflow page */
addr = OADDR_OF(splitnum, offset);
#ifdef DEBUG2
(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
addr, free_bit, free_page);
#endif
return (addr);
found:
bit = bit + first_free(freep[j]);
SETBIT(freep, bit);
#ifdef DEBUG2
tmp1 = bit;
tmp2 = i;
#endif
/*
* Bits are addressed starting with 0, but overflow pages are addressed
* beginning at 1. Bit is a bit addressnumber, so we need to increment
* it to convert it to a page number.
*/
bit = 1 + bit + (i * (hashp->BSIZE << BYTE_SHIFT));
if (bit >= hashp->LAST_FREED)
hashp->LAST_FREED = bit - 1;
/* Calculate the split number for this page */
for (i = 0; (i < splitnum) && (bit > hashp->SPARES[i]); i++);
offset = (i ? bit - hashp->SPARES[i - 1] : bit);
if (offset >= SPLITMASK)
return (0); /* Out of overflow pages */
addr = OADDR_OF(i, offset);
#ifdef DEBUG2
(void)fprintf(stderr, "OVERFLOW_PAGE: ADDR: %d BIT: %d PAGE %d\n",
addr, tmp1, tmp2);
#endif
/* Allocate and return the overflow page */
return (addr);
}
/*
* Mark this overflow page as free.
*/
extern void
__free_ovflpage(hashp, obufp)
HTAB *hashp;
BUFHEAD *obufp;
{
register u_int16_t addr;
u_int32_t *freep;
int bit_address, free_page, free_bit;
u_int16_t ndx;
addr = obufp->addr;
#ifdef DEBUG1
(void)fprintf(stderr, "Freeing %d\n", addr);
#endif
ndx = (((u_int16_t)addr) >> SPLITSHIFT);
bit_address =
(ndx ? hashp->SPARES[ndx - 1] : 0) + (addr & SPLITMASK) - 1;
if (bit_address < hashp->LAST_FREED)
hashp->LAST_FREED = bit_address;
free_page = (bit_address >> (hashp->BSHIFT + BYTE_SHIFT));
free_bit = bit_address & ((hashp->BSIZE << BYTE_SHIFT) - 1);
if (!(freep = hashp->mapp[free_page]))
freep = fetch_bitmap(hashp, free_page);
#ifdef DEBUG
/*
* This had better never happen. It means we tried to read a bitmap
* that has already had overflow pages allocated off it, and we
* failed to read it from the file.
*/
if (!freep)
assert(0);
#endif
CLRBIT(freep, free_bit);
#ifdef DEBUG2
(void)fprintf(stderr, "FREE_OVFLPAGE: ADDR: %d BIT: %d PAGE %d\n",
obufp->addr, free_bit, free_page);
#endif
__reclaim_buf(hashp, obufp);
}
/*
* Returns:
* 0 success
* -1 failure
*/
static int
open_temp(hashp)
HTAB *hashp;
{
sigset_t set, oset;
static char namestr[] = "_hashXXXXXX";
/* Block signals; make sure file goes away at process exit. */
(void)sigfillset(&set);
(void)sigprocmask(SIG_BLOCK, &set, &oset);
if ((hashp->fp = mkstemp(namestr)) != -1) {
(void)unlink(namestr);
(void)fcntl(hashp->fp, F_SETFD, 1);
}
(void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
return (hashp->fp != -1 ? 0 : -1);
}
/*
* We have to know that the key will fit, but the last entry on the page is
* an overflow pair, so we need to shift things.
*/
static void
squeeze_key(sp, key, val)
u_int16_t *sp;
const DBT *key, *val;
{
register char *p;
u_int16_t free_space, n, off, pageno;
p = (char *)sp;
n = sp[0];
free_space = FREESPACE(sp);
off = OFFSET(sp);
pageno = sp[n - 1];
off -= key->size;
sp[n - 1] = off;
memmove(p + off, key->data, key->size);
off -= val->size;
sp[n] = off;
memmove(p + off, val->data, val->size);
sp[0] = n + 2;
sp[n + 1] = pageno;
sp[n + 2] = OVFLPAGE;
FREESPACE(sp) = free_space - PAIRSIZE(key, val);
OFFSET(sp) = off;
}
static u_int32_t *
fetch_bitmap(hashp, ndx)
HTAB *hashp;
int ndx;
{
if (ndx >= hashp->nmaps)
return (NULL);
if ((hashp->mapp[ndx] = (u_int32_t *)malloc(hashp->BSIZE)) == NULL)
return (NULL);
if (__get_page(hashp,
(char *)hashp->mapp[ndx], hashp->BITMAPS[ndx], 0, 1, 1)) {
free(hashp->mapp[ndx]);
return (NULL);
}
return (hashp->mapp[ndx]);
}
#ifdef DEBUG4
int
print_chain(addr)
int addr;
{
BUFHEAD *bufp;
short *bp, oaddr;
(void)fprintf(stderr, "%d ", addr);
bufp = __get_buf(hashp, addr, NULL, 0);
bp = (short *)bufp->page;
while (bp[0] && ((bp[bp[0]] == OVFLPAGE) ||
((bp[0] > 2) && bp[2] < REAL_KEY))) {
oaddr = bp[bp[0] - 1];
(void)fprintf(stderr, "%d ", (int)oaddr);
bufp = __get_buf(hashp, (int)oaddr, bufp, 0);
bp = (short *)bufp->page;
}
(void)fprintf(stderr, "\n");
}
#endif
+215
View File
@@ -0,0 +1,215 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)ndbm.c 8.4 (Berkeley) 7/21/94";
#endif /* LIBC_SCCS and not lint */
/*
* This package provides a dbm compatible interface to the new hashing
* package described in db(3).
*/
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ndbm.h>
#include "hash.h"
/*
* Returns:
* *DBM on success
* NULL on failure
*/
extern DBM *
dbm_open(file, flags, mode)
const char *file;
int flags, mode;
{
DBM *db;
HASHINFO info;
const size_t len = strlen(file) + sizeof (DBM_SUFFIX);
#ifdef __GNUC__
char path[len];
#else
char *path = malloc(len);
if (path == NULL)
return NULL;
#endif
info.bsize = 4096;
info.ffactor = 40;
info.nelem = 1;
info.cachesize = 0;
info.hash = NULL;
info.lorder = 0;
(void)strcpy(path, file);
(void)strcat(path, DBM_SUFFIX);
db = (DBM *)__hash_open(path, flags, mode, &info, 0);
#ifndef __GNUC__
free(path);
#endif
return db;
}
extern void
dbm_close(db)
DBM *db;
{
(void)(db->close)(db);
}
/*
* Returns:
* DATUM on success
* NULL on failure
*/
extern datum
dbm_fetch(db, key)
DBM *db;
datum key;
{
datum retval;
int status;
status = (db->get)(db, (DBT *)&key, (DBT *)&retval, 0);
if (status) {
retval.dptr = NULL;
retval.dsize = 0;
}
return (retval);
}
/*
* Returns:
* DATUM on success
* NULL on failure
*/
extern datum
dbm_firstkey(db)
DBM *db;
{
int status;
datum retdata, retkey;
status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_FIRST);
if (status)
retkey.dptr = NULL;
return (retkey);
}
/*
* Returns:
* DATUM on success
* NULL on failure
*/
extern datum
dbm_nextkey(db)
DBM *db;
{
int status;
datum retdata, retkey;
status = (db->seq)(db, (DBT *)&retkey, (DBT *)&retdata, R_NEXT);
if (status)
retkey.dptr = NULL;
return (retkey);
}
/*
* Returns:
* 0 on success
* <0 failure
*/
extern int
dbm_delete(db, key)
DBM *db;
datum key;
{
int status;
status = (db->del)(db, (DBT *)&key, 0);
if (status)
return (-1);
else
return (0);
}
/*
* Returns:
* 0 on success
* <0 failure
* 1 if DBM_INSERT and entry exists
*/
extern int
dbm_store(db, key, content, flags)
DBM *db;
datum key, content;
int flags;
{
return ((db->put)(db, (DBT *)&key, (DBT *)&content,
(flags == DBM_INSERT) ? R_NOOVERWRITE : 0));
}
extern int
dbm_error(db)
DBM *db;
{
HTAB *hp;
hp = (HTAB *)db->internal;
return (hp->errnum);
}
extern int
dbm_clearerr(db)
DBM *db;
{
HTAB *hp;
hp = (HTAB *)db->internal;
hp->errnum = 0;
return (0);
}
extern int
dbm_dirfno(db)
DBM *db;
{
return(((HTAB *)db->internal)->fp);
}
+92
View File
@@ -0,0 +1,92 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)page.h 8.2 (Berkeley) 5/31/94
*/
/*
* Definitions for hashing page file format.
*/
/*
* routines dealing with a data page
*
* page format:
* +------------------------------+
* p | n | keyoff | datoff | keyoff |
* +------------+--------+--------+
* | datoff | free | ptr | --> |
* +--------+---------------------+
* | F R E E A R E A |
* +--------------+---------------+
* | <---- - - - | data |
* +--------+-----+----+----------+
* | key | data | key |
* +--------+----------+----------+
*
* Pointer to the free space is always: p[p[0] + 2]
* Amount of free space on the page is: p[p[0] + 1]
*/
/*
* How many bytes required for this pair?
* 2 shorts in the table at the top of the page + room for the
* key and room for the data
*
* We prohibit entering a pair on a page unless there is also room to append
* an overflow page. The reason for this it that you can get in a situation
* where a single key/data pair fits on a page, but you can't append an
* overflow page and later you'd have to split the key/data and handle like
* a big pair.
* You might as well do this up front.
*/
#define PAIRSIZE(K,D) (2*sizeof(u_int16_t) + (K)->size + (D)->size)
#define BIGOVERHEAD (4*sizeof(u_int16_t))
#define KEYSIZE(K) (4*sizeof(u_int16_t) + (K)->size);
#define OVFLSIZE (2*sizeof(u_int16_t))
#define FREESPACE(P) ((P)[(P)[0]+1])
#define OFFSET(P) ((P)[(P)[0]+2])
#define PAIRFITS(P,K,D) \
(((P)[2] >= REAL_KEY) && \
(PAIRSIZE((K),(D)) + OVFLSIZE) <= FREESPACE((P)))
#define PAGE_META(N) (((N)+3) * sizeof(u_int16_t))
typedef struct {
BUFHEAD *newp;
BUFHEAD *oldp;
BUFHEAD *nextp;
u_int16_t next_addr;
} SPLIT_RETURN;
+99
View File
@@ -0,0 +1,99 @@
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mpool.h 8.2 (Berkeley) 7/14/94
*/
#include <sys/queue.h>
/*
* The memory pool scheme is a simple one. Each in-memory page is referenced
* by a bucket which is threaded in up to two of three ways. All active pages
* are threaded on a hash chain (hashed by page number) and an lru chain.
* Inactive pages are threaded on a free chain. Each reference to a memory
* pool is handed an opaque MPOOL cookie which stores all of this information.
*/
#define HASHSIZE 128
#define HASHKEY(pgno) ((pgno - 1) % HASHSIZE)
/* The BKT structures are the elements of the queues. */
typedef struct _bkt {
CIRCLEQ_ENTRY(_bkt) hq; /* hash queue */
CIRCLEQ_ENTRY(_bkt) q; /* lru queue */
void *page; /* page */
pgno_t pgno; /* page number */
#define MPOOL_DIRTY 0x01 /* page needs to be written */
#define MPOOL_PINNED 0x02 /* page is pinned into memory */
u_int8_t flags; /* flags */
} BKT;
typedef struct MPOOL {
CIRCLEQ_HEAD(_lqh, _bkt) lqh; /* lru queue head */
/* hash queue array */
CIRCLEQ_HEAD(_hqh, _bkt) hqh[HASHSIZE];
pgno_t curcache; /* current number of cached pages */
pgno_t maxcache; /* max number of cached pages */
pgno_t npages; /* number of pages in the file */
u_long pagesize; /* file page size */
int fd; /* file descriptor */
/* page in conversion routine */
void (*pgin) __P((void *, pgno_t, void *));
/* page out conversion routine */
void (*pgout) __P((void *, pgno_t, void *));
void *pgcookie; /* cookie for page in/out routines */
#ifdef STATISTICS
u_long cachehit;
u_long cachemiss;
u_long pagealloc;
u_long pageflush;
u_long pageget;
u_long pagenew;
u_long pageput;
u_long pageread;
u_long pagewrite;
#endif
} MPOOL;
__BEGIN_DECLS
MPOOL *mpool_open __P((void *, int, pgno_t, pgno_t));
void mpool_filter __P((MPOOL *, void (*)(void *, pgno_t, void *),
void (*)(void *, pgno_t, void *), void *));
void *mpool_new __P((MPOOL *, pgno_t *));
void *mpool_get __P((MPOOL *, pgno_t, u_int));
int mpool_put __P((MPOOL *, void *, u_int));
int mpool_sync __P((MPOOL *));
int mpool_close __P((MPOOL *));
#ifdef STATISTICS
void mpool_stat __P((MPOOL *));
#endif
__END_DECLS
+463
View File
@@ -0,0 +1,463 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)mpool.c 8.5 (Berkeley) 7/26/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <db.h>
#define __MPOOLINTERFACE_PRIVATE
#include <mpool.h>
static BKT *mpool_bkt __P((MPOOL *));
static BKT *mpool_look __P((MPOOL *, pgno_t));
static int mpool_write __P((MPOOL *, BKT *));
/*
* mpool_open --
* Initialize a memory pool.
*/
MPOOL *
mpool_open(key, fd, pagesize, maxcache)
void *key;
int fd;
pgno_t pagesize, maxcache;
{
struct stat sb;
MPOOL *mp;
int entry;
/*
* Get information about the file.
*
* XXX
* We don't currently handle pipes, although we should.
*/
if (fstat(fd, &sb))
return (NULL);
if (!S_ISREG(sb.st_mode)) {
errno = ESPIPE;
return (NULL);
}
/* Allocate and initialize the MPOOL cookie. */
if ((mp = (MPOOL *)calloc(1, sizeof(MPOOL))) == NULL)
return (NULL);
CIRCLEQ_INIT(&mp->lqh);
for (entry = 0; entry < HASHSIZE; ++entry)
CIRCLEQ_INIT(&mp->hqh[entry]);
mp->maxcache = maxcache;
mp->npages = sb.st_size / pagesize;
mp->pagesize = pagesize;
mp->fd = fd;
return (mp);
}
/*
* mpool_filter --
* Initialize input/output filters.
*/
void
mpool_filter(mp, pgin, pgout, pgcookie)
MPOOL *mp;
void (*pgin) __P((void *, pgno_t, void *));
void (*pgout) __P((void *, pgno_t, void *));
void *pgcookie;
{
mp->pgin = pgin;
mp->pgout = pgout;
mp->pgcookie = pgcookie;
}
/*
* mpool_new --
* Get a new page of memory.
*/
void *
mpool_new(mp, pgnoaddr)
MPOOL *mp;
pgno_t *pgnoaddr;
{
struct _hqh *head;
BKT *bp;
if (mp->npages == MAX_PAGE_NUMBER) {
(void)fprintf(stderr, "mpool_new: page allocation overflow.\n");
abort();
}
#ifdef STATISTICS
++mp->pagenew;
#endif
/*
* Get a BKT from the cache. Assign a new page number, attach
* it to the head of the hash chain, the tail of the lru chain,
* and return.
*/
if ((bp = mpool_bkt(mp)) == NULL)
return (NULL);
*pgnoaddr = bp->pgno = mp->npages++;
bp->flags = MPOOL_PINNED;
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_INSERT_HEAD(head, bp, hq);
CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
return (bp->page);
}
/*
* mpool_get
* Get a page.
*/
void *
mpool_get(mp, pgno, flags)
MPOOL *mp;
pgno_t pgno;
u_int flags; /* XXX not used? */
{
struct _hqh *head;
BKT *bp;
off_t off;
int nr;
/* Check for attempt to retrieve a non-existent page. */
if (pgno >= mp->npages) {
errno = EINVAL;
return (NULL);
}
#ifdef STATISTICS
++mp->pageget;
#endif
/* Check for a page that is cached. */
if ((bp = mpool_look(mp, pgno)) != NULL) {
#ifdef DEBUG
if (bp->flags & MPOOL_PINNED) {
(void)fprintf(stderr,
"mpool_get: page %d already pinned\n", bp->pgno);
abort();
}
#endif
/*
* Move the page to the head of the hash chain and the tail
* of the lru chain.
*/
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_REMOVE(head, bp, hq);
CIRCLEQ_INSERT_HEAD(head, bp, hq);
CIRCLEQ_REMOVE(&mp->lqh, bp, q);
CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
/* Return a pinned page. */
bp->flags |= MPOOL_PINNED;
return (bp->page);
}
/* Get a page from the cache. */
if ((bp = mpool_bkt(mp)) == NULL)
return (NULL);
/* Read in the contents. */
#ifdef STATISTICS
++mp->pageread;
#endif
off = mp->pagesize * pgno;
if (lseek(mp->fd, off, SEEK_SET) != off)
return (NULL);
if ((nr = read(mp->fd, bp->page, mp->pagesize)) != mp->pagesize) {
if (nr >= 0)
errno = EFTYPE;
return (NULL);
}
/* Set the page number, pin the page. */
bp->pgno = pgno;
bp->flags = MPOOL_PINNED;
/*
* Add the page to the head of the hash chain and the tail
* of the lru chain.
*/
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_INSERT_HEAD(head, bp, hq);
CIRCLEQ_INSERT_TAIL(&mp->lqh, bp, q);
/* Run through the user's filter. */
if (mp->pgin != NULL)
(mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
return (bp->page);
}
/*
* mpool_put
* Return a page.
*/
int
mpool_put(mp, page, flags)
MPOOL *mp;
void *page;
u_int flags;
{
BKT *bp;
#ifdef STATISTICS
++mp->pageput;
#endif
bp = (BKT *)((char *)page - sizeof(BKT));
#ifdef DEBUG
if (!(bp->flags & MPOOL_PINNED)) {
(void)fprintf(stderr,
"mpool_put: page %d not pinned\n", bp->pgno);
abort();
}
#endif
bp->flags &= ~MPOOL_PINNED;
bp->flags |= flags & MPOOL_DIRTY;
return (RET_SUCCESS);
}
/*
* mpool_close
* Close the buffer pool.
*/
int
mpool_close(mp)
MPOOL *mp;
{
BKT *bp;
/* Free up any space allocated to the lru pages. */
while ((bp = mp->lqh.cqh_first) != (void *)&mp->lqh) {
CIRCLEQ_REMOVE(&mp->lqh, mp->lqh.cqh_first, q);
free(bp);
}
/* Free the MPOOL cookie. */
free(mp);
return (RET_SUCCESS);
}
/*
* mpool_sync
* Sync the pool to disk.
*/
int
mpool_sync(mp)
MPOOL *mp;
{
BKT *bp;
/* Walk the lru chain, flushing any dirty pages to disk. */
for (bp = mp->lqh.cqh_first;
bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
if (bp->flags & MPOOL_DIRTY &&
mpool_write(mp, bp) == RET_ERROR)
return (RET_ERROR);
/* Sync the file descriptor. */
return (fsync(mp->fd) ? RET_ERROR : RET_SUCCESS);
}
/*
* mpool_bkt
* Get a page from the cache (or create one).
*/
static BKT *
mpool_bkt(mp)
MPOOL *mp;
{
struct _hqh *head;
BKT *bp;
/* If under the max cached, always create a new page. */
if (mp->curcache < mp->maxcache)
goto new;
/*
* If the cache is max'd out, walk the lru list for a buffer we
* can flush. If we find one, write it (if necessary) and take it
* off any lists. If we don't find anything we grow the cache anyway.
* The cache never shrinks.
*/
for (bp = mp->lqh.cqh_first;
bp != (void *)&mp->lqh; bp = bp->q.cqe_next)
if (!(bp->flags & MPOOL_PINNED)) {
/* Flush if dirty. */
if (bp->flags & MPOOL_DIRTY &&
mpool_write(mp, bp) == RET_ERROR)
return (NULL);
#ifdef STATISTICS
++mp->pageflush;
#endif
/* Remove from the hash and lru queues. */
head = &mp->hqh[HASHKEY(bp->pgno)];
CIRCLEQ_REMOVE(head, bp, hq);
CIRCLEQ_REMOVE(&mp->lqh, bp, q);
#ifdef DEBUG
{ void *spage;
spage = bp->page;
memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
bp->page = spage;
}
#endif
return (bp);
}
new: if ((bp = (BKT *)malloc(sizeof(BKT) + mp->pagesize)) == NULL)
return (NULL);
#ifdef STATISTICS
++mp->pagealloc;
#endif
#if defined(DEBUG) || defined(PURIFY)
memset(bp, 0xff, sizeof(BKT) + mp->pagesize);
#endif
bp->page = (char *)bp + sizeof(BKT);
++mp->curcache;
return (bp);
}
/*
* mpool_write
* Write a page to disk.
*/
static int
mpool_write(mp, bp)
MPOOL *mp;
BKT *bp;
{
off_t off;
#ifdef STATISTICS
++mp->pagewrite;
#endif
/* Run through the user's filter. */
if (mp->pgout)
(mp->pgout)(mp->pgcookie, bp->pgno, bp->page);
off = mp->pagesize * bp->pgno;
if (lseek(mp->fd, off, SEEK_SET) != off)
return (RET_ERROR);
if (write(mp->fd, bp->page, mp->pagesize) != mp->pagesize)
return (RET_ERROR);
bp->flags &= ~MPOOL_DIRTY;
return (RET_SUCCESS);
}
/*
* mpool_look
* Lookup a page in the cache.
*/
static BKT *
mpool_look(mp, pgno)
MPOOL *mp;
pgno_t pgno;
{
struct _hqh *head;
BKT *bp;
head = &mp->hqh[HASHKEY(pgno)];
for (bp = head->cqh_first; bp != (void *)head; bp = bp->hq.cqe_next)
if (bp->pgno == pgno) {
#ifdef STATISTICS
++mp->cachehit;
#endif
return (bp);
}
#ifdef STATISTICS
++mp->cachemiss;
#endif
return (NULL);
}
#ifdef STATISTICS
/*
* mpool_stat
* Print out cache statistics.
*/
void
mpool_stat(mp)
MPOOL *mp;
{
BKT *bp;
int cnt;
char *sep;
(void)fprintf(stderr, "%lu pages in the file\n", mp->npages);
(void)fprintf(stderr,
"page size %lu, cacheing %lu pages of %lu page max cache\n",
mp->pagesize, mp->curcache, mp->maxcache);
(void)fprintf(stderr, "%lu page puts, %lu page gets, %lu page new\n",
mp->pageput, mp->pageget, mp->pagenew);
(void)fprintf(stderr, "%lu page allocs, %lu page flushes\n",
mp->pagealloc, mp->pageflush);
if (mp->cachehit + mp->cachemiss)
(void)fprintf(stderr,
"%.0f%% cache hit rate (%lu hits, %lu misses)\n",
((double)mp->cachehit / (mp->cachehit + mp->cachemiss))
* 100, mp->cachehit, mp->cachemiss);
(void)fprintf(stderr, "%lu page reads, %lu page writes\n",
mp->pageread, mp->pagewrite);
sep = "";
cnt = 0;
for (bp = mp->lqh.cqh_first;
bp != (void *)&mp->lqh; bp = bp->q.cqe_next) {
(void)fprintf(stderr, "%s%d", sep, bp->pgno);
if (bp->flags & MPOOL_DIRTY)
(void)fprintf(stderr, "d");
if (bp->flags & MPOOL_PINNED)
(void)fprintf(stderr, "P");
if (++cnt == 10) {
sep = "\n";
cnt = 0;
} else
sep = ", ";
}
(void)fprintf(stderr, "\n");
}
#endif
+79
View File
@@ -0,0 +1,79 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Margo Seltzer.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ndbm.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _NDBM_H_
#define _NDBM_H_
#include <db.h>
/* Map dbm interface onto db(3). */
#define DBM_RDONLY O_RDONLY
/* Flags to dbm_store(). */
#define DBM_INSERT 0
#define DBM_REPLACE 1
/*
* The db(3) support for ndbm(3) always appends this suffix to the
* file name to avoid overwriting the user's original database.
*/
#define DBM_SUFFIX ".db"
typedef struct {
char *dptr;
int dsize;
} datum;
typedef DB DBM;
#define dbm_pagfno(a) DBM_PAGFNO_NOT_AVAILABLE
__BEGIN_DECLS
void dbm_close __P((DBM *));
int dbm_delete __P((DBM *, datum));
datum dbm_fetch __P((DBM *, datum));
datum dbm_firstkey __P((DBM *));
long dbm_forder __P((DBM *, datum));
datum dbm_nextkey __P((DBM *));
DBM *dbm_open __P((const char *, int, int));
int dbm_store __P((DBM *, datum, datum, int));
int dbm_dirfno __P((DBM *));
int dbm_error __P((DBM *));
int dbm_clearerr __P((DBM *));
__END_DECLS
#endif /* !_NDBM_H_ */
+54
View File
@@ -0,0 +1,54 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)extern.h 8.3 (Berkeley) 6/4/94
*/
#include "../btree/extern.h"
int __rec_close __P((DB *));
int __rec_delete __P((const DB *, const DBT *, u_int));
int __rec_dleaf __P((BTREE *, PAGE *, u_int32_t));
int __rec_fd __P((const DB *));
int __rec_fmap __P((BTREE *, recno_t));
int __rec_fout __P((BTREE *));
int __rec_fpipe __P((BTREE *, recno_t));
int __rec_get __P((const DB *, const DBT *, DBT *, u_int));
int __rec_iput __P((BTREE *, recno_t, const DBT *, u_int));
int __rec_put __P((const DB *dbp, DBT *, const DBT *, u_int));
int __rec_ret __P((BTREE *, EPG *, recno_t, DBT *, DBT *));
EPG *__rec_search __P((BTREE *, recno_t, enum SRCHOP));
int __rec_seq __P((const DB *, DBT *, DBT *, u_int));
int __rec_sync __P((const DB *, u_int));
int __rec_vmap __P((BTREE *, recno_t));
int __rec_vout __P((BTREE *));
int __rec_vpipe __P((BTREE *, recno_t));
+182
View File
@@ -0,0 +1,182 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_close.c 8.6 (Berkeley) 8/18/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/mman.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <db.h>
#include "recno.h"
/*
* __REC_CLOSE -- Close a recno tree.
*
* Parameters:
* dbp: pointer to access method
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__rec_close(dbp)
DB *dbp;
{
BTREE *t;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
if (__rec_sync(dbp, 0) == RET_ERROR)
return (RET_ERROR);
/* Committed to closing. */
status = RET_SUCCESS;
if (F_ISSET(t, R_MEMMAPPED) && munmap(t->bt_smap, t->bt_msize))
status = RET_ERROR;
if (!F_ISSET(t, R_INMEM))
if (F_ISSET(t, R_CLOSEFP)) {
if (fclose(t->bt_rfp))
status = RET_ERROR;
} else
if (close(t->bt_rfd))
status = RET_ERROR;
if (__bt_close(dbp) == RET_ERROR)
status = RET_ERROR;
return (status);
}
/*
* __REC_SYNC -- sync the recno tree to disk.
*
* Parameters:
* dbp: pointer to access method
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__rec_sync(dbp, flags)
const DB *dbp;
u_int flags;
{
struct iovec iov[2];
BTREE *t;
DBT data, key;
off_t off;
recno_t scursor, trec;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
if (flags == R_RECNOSYNC)
return (__bt_sync(dbp, 0));
if (F_ISSET(t, R_RDONLY | R_INMEM) || !F_ISSET(t, R_MODIFIED))
return (RET_SUCCESS);
/* Read any remaining records into the tree. */
if (!F_ISSET(t, R_EOF) && t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
return (RET_ERROR);
/* Rewind the file descriptor. */
if (lseek(t->bt_rfd, (off_t)0, SEEK_SET) != 0)
return (RET_ERROR);
/* Save the cursor. */
scursor = t->bt_cursor.rcursor;
key.size = sizeof(recno_t);
key.data = &trec;
if (F_ISSET(t, R_FIXLEN)) {
/*
* We assume that fixed length records are all fixed length.
* Any that aren't are either EINVAL'd or corrected by the
* record put code.
*/
status = (dbp->seq)(dbp, &key, &data, R_FIRST);
while (status == RET_SUCCESS) {
if (write(t->bt_rfd, data.data, data.size) != data.size)
return (RET_ERROR);
status = (dbp->seq)(dbp, &key, &data, R_NEXT);
}
} else {
iov[1].iov_base = &t->bt_bval;
iov[1].iov_len = 1;
status = (dbp->seq)(dbp, &key, &data, R_FIRST);
while (status == RET_SUCCESS) {
iov[0].iov_base = data.data;
iov[0].iov_len = data.size;
if (writev(t->bt_rfd, iov, 2) != data.size + 1)
return (RET_ERROR);
status = (dbp->seq)(dbp, &key, &data, R_NEXT);
}
}
/* Restore the cursor. */
t->bt_cursor.rcursor = scursor;
if (status == RET_ERROR)
return (RET_ERROR);
if ((off = lseek(t->bt_rfd, (off_t)0, SEEK_CUR)) == -1)
return (RET_ERROR);
if (ftruncate(t->bt_rfd, off))
return (RET_ERROR);
F_CLR(t, R_MODIFIED);
return (RET_SUCCESS);
}
+197
View File
@@ -0,0 +1,197 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_delete.c 8.7 (Berkeley) 7/14/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <db.h>
#include "recno.h"
static int rec_rdelete __P((BTREE *, recno_t));
/*
* __REC_DELETE -- Delete the item(s) referenced by a key.
*
* Parameters:
* dbp: pointer to access method
* key: key to delete
* flags: R_CURSOR if deleting what the cursor references
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
int
__rec_delete(dbp, key, flags)
const DB *dbp;
const DBT *key;
u_int flags;
{
BTREE *t;
recno_t nrec;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
switch(flags) {
case 0:
if ((nrec = *(recno_t *)key->data) == 0)
goto einval;
if (nrec > t->bt_nrecs)
return (RET_SPECIAL);
--nrec;
status = rec_rdelete(t, nrec);
break;
case R_CURSOR:
if (!F_ISSET(&t->bt_cursor, CURS_INIT))
goto einval;
if (t->bt_nrecs == 0)
return (RET_SPECIAL);
status = rec_rdelete(t, t->bt_cursor.rcursor - 1);
if (status == RET_SUCCESS)
--t->bt_cursor.rcursor;
break;
default:
einval: errno = EINVAL;
return (RET_ERROR);
}
if (status == RET_SUCCESS)
F_SET(t, B_MODIFIED | R_MODIFIED);
return (status);
}
/*
* REC_RDELETE -- Delete the data matching the specified key.
*
* Parameters:
* tree: tree
* nrec: record to delete
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
static int
rec_rdelete(t, nrec)
BTREE *t;
recno_t nrec;
{
EPG *e;
PAGE *h;
int status;
/* Find the record; __rec_search pins the page. */
if ((e = __rec_search(t, nrec, SDELETE)) == NULL)
return (RET_ERROR);
/* Delete the record. */
h = e->page;
status = __rec_dleaf(t, h, e->index);
if (status != RET_SUCCESS) {
mpool_put(t->bt_mp, h, 0);
return (status);
}
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
/*
* __REC_DLEAF -- Delete a single record from a recno leaf page.
*
* Parameters:
* t: tree
* index: index on current page to delete
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__rec_dleaf(t, h, index)
BTREE *t;
PAGE *h;
u_int32_t index;
{
RLEAF *rl;
indx_t *ip, cnt, offset;
u_int32_t nbytes;
char *from;
void *to;
/*
* Delete a record from a recno leaf page. Internal records are never
* deleted from internal pages, regardless of the records that caused
* them to be added being deleted. Pages made empty by deletion are
* not reclaimed. They are, however, made available for reuse.
*
* Pack the remaining entries at the end of the page, shift the indices
* down, overwriting the deleted record and its index. If the record
* uses overflow pages, make them available for reuse.
*/
to = rl = GETRLEAF(h, index);
if (rl->flags & P_BIGDATA && __ovfl_delete(t, rl->bytes) == RET_ERROR)
return (RET_ERROR);
nbytes = NRLEAF(rl);
/*
* Compress the key/data pairs. Compress and adjust the [BR]LEAF
* offsets. Reset the headers.
*/
from = (char *)h + h->upper;
memmove(from + nbytes, from, (char *)to - from);
h->upper += nbytes;
offset = h->linp[index];
for (cnt = &h->linp[index] - (ip = &h->linp[0]); cnt--; ++ip)
if (ip[0] < offset)
ip[0] += nbytes;
for (cnt = &h->linp[NEXTINDEX(h)] - ip; --cnt; ++ip)
ip[0] = ip[1] < offset ? ip[1] + nbytes : ip[1];
h->lower -= sizeof(indx_t);
--t->bt_nrecs;
return (RET_SUCCESS);
}
+311
View File
@@ -0,0 +1,311 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_get.c 8.9 (Berkeley) 8/18/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <db.h>
#include "recno.h"
/*
* __REC_GET -- Get a record from the btree.
*
* Parameters:
* dbp: pointer to access method
* key: key to find
* data: data to return
* flag: currently unused
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key not found.
*/
int
__rec_get(dbp, key, data, flags)
const DB *dbp;
const DBT *key;
DBT *data;
u_int flags;
{
BTREE *t;
EPG *e;
recno_t nrec;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* Get currently doesn't take any flags, and keys of 0 are illegal. */
if (flags || (nrec = *(recno_t *)key->data) == 0) {
errno = EINVAL;
return (RET_ERROR);
}
/*
* If we haven't seen this record yet, try to find it in the
* original file.
*/
if (nrec > t->bt_nrecs) {
if (F_ISSET(t, R_EOF | R_INMEM))
return (RET_SPECIAL);
if ((status = t->bt_irec(t, nrec)) != RET_SUCCESS)
return (status);
}
--nrec;
if ((e = __rec_search(t, nrec, SEARCH)) == NULL)
return (RET_ERROR);
status = __rec_ret(t, e, 0, NULL, data);
if (F_ISSET(t, B_DB_LOCK))
mpool_put(t->bt_mp, e->page, 0);
else
t->bt_pinned = e->page;
return (status);
}
/*
* __REC_FPIPE -- Get fixed length records from a pipe.
*
* Parameters:
* t: tree
* cnt: records to read
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__rec_fpipe(t, top)
BTREE *t;
recno_t top;
{
DBT data;
recno_t nrec;
size_t len;
int ch;
u_char *p;
if (t->bt_rdata.size < t->bt_reclen) {
t->bt_rdata.data = t->bt_rdata.data == NULL ?
malloc(t->bt_reclen) :
realloc(t->bt_rdata.data, t->bt_reclen);
if (t->bt_rdata.data == NULL)
return (RET_ERROR);
t->bt_rdata.size = t->bt_reclen;
}
data.data = t->bt_rdata.data;
data.size = t->bt_reclen;
for (nrec = t->bt_nrecs; nrec < top;) {
len = t->bt_reclen;
for (p = t->bt_rdata.data;; *p++ = ch)
if ((ch = getc(t->bt_rfp)) == EOF || !--len) {
if (ch != EOF)
*p = ch;
if (len != 0)
memset(p, t->bt_bval, len);
if (__rec_iput(t,
nrec, &data, 0) != RET_SUCCESS)
return (RET_ERROR);
++nrec;
break;
}
if (ch == EOF)
break;
}
if (nrec < top) {
F_SET(t, R_EOF);
return (RET_SPECIAL);
}
return (RET_SUCCESS);
}
/*
* __REC_VPIPE -- Get variable length records from a pipe.
*
* Parameters:
* t: tree
* cnt: records to read
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__rec_vpipe(t, top)
BTREE *t;
recno_t top;
{
DBT data;
recno_t nrec;
indx_t len;
size_t sz;
int bval, ch;
u_char *p;
bval = t->bt_bval;
for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
for (p = t->bt_rdata.data,
sz = t->bt_rdata.size;; *p++ = ch, --sz) {
if ((ch = getc(t->bt_rfp)) == EOF || ch == bval) {
data.data = t->bt_rdata.data;
data.size = p - (u_char *)t->bt_rdata.data;
if (ch == EOF && data.size == 0)
break;
if (__rec_iput(t, nrec, &data, 0)
!= RET_SUCCESS)
return (RET_ERROR);
break;
}
if (sz == 0) {
len = p - (u_char *)t->bt_rdata.data;
t->bt_rdata.size += (sz = 256);
t->bt_rdata.data = t->bt_rdata.data == NULL ?
malloc(t->bt_rdata.size) :
realloc(t->bt_rdata.data, t->bt_rdata.size);
if (t->bt_rdata.data == NULL)
return (RET_ERROR);
p = (u_char *)t->bt_rdata.data + len;
}
}
if (ch == EOF)
break;
}
if (nrec < top) {
F_SET(t, R_EOF);
return (RET_SPECIAL);
}
return (RET_SUCCESS);
}
/*
* __REC_FMAP -- Get fixed length records from a file.
*
* Parameters:
* t: tree
* cnt: records to read
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__rec_fmap(t, top)
BTREE *t;
recno_t top;
{
DBT data;
recno_t nrec;
u_char *sp, *ep, *p;
size_t len;
if (t->bt_rdata.size < t->bt_reclen) {
t->bt_rdata.data = t->bt_rdata.data == NULL ?
malloc(t->bt_reclen) :
realloc(t->bt_rdata.data, t->bt_reclen);
if (t->bt_rdata.data == NULL)
return (RET_ERROR);
t->bt_rdata.size = t->bt_reclen;
}
data.data = t->bt_rdata.data;
data.size = t->bt_reclen;
sp = (u_char *)t->bt_cmap;
ep = (u_char *)t->bt_emap;
for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
if (sp >= ep) {
F_SET(t, R_EOF);
return (RET_SPECIAL);
}
len = t->bt_reclen;
for (p = t->bt_rdata.data;
sp < ep && len > 0; *p++ = *sp++, --len);
if (len != 0)
memset(p, t->bt_bval, len);
if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
return (RET_ERROR);
}
t->bt_cmap = (caddr_t)sp;
return (RET_SUCCESS);
}
/*
* __REC_VMAP -- Get variable length records from a file.
*
* Parameters:
* t: tree
* cnt: records to read
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__rec_vmap(t, top)
BTREE *t;
recno_t top;
{
DBT data;
u_char *sp, *ep;
recno_t nrec;
int bval;
sp = (u_char *)t->bt_cmap;
ep = (u_char *)t->bt_emap;
bval = t->bt_bval;
for (nrec = t->bt_nrecs; nrec < top; ++nrec) {
if (sp >= ep) {
F_SET(t, R_EOF);
return (RET_SPECIAL);
}
for (data.data = sp; sp < ep && *sp != bval; ++sp);
data.size = sp - (u_char *)data.data;
if (__rec_iput(t, nrec, &data, 0) != RET_SUCCESS)
return (RET_ERROR);
++sp;
}
t->bt_cmap = (caddr_t)sp;
return (RET_SUCCESS);
}
+241
View File
@@ -0,0 +1,241 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Mike Olson.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_open.c 8.10 (Berkeley) 9/1/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <unistd.h>
#include <db.h>
#include "recno.h"
DB *
__rec_open(fname, flags, mode, openinfo, dflags)
const char *fname;
int flags, mode, dflags;
const RECNOINFO *openinfo;
{
BTREE *t;
BTREEINFO btopeninfo;
DB *dbp;
PAGE *h;
struct stat sb;
int rfd, sverrno;
/* Open the user's file -- if this fails, we're done. */
if (fname != NULL && (rfd = open(fname, flags, mode)) < 0)
return (NULL);
/* Create a btree in memory (backed by disk). */
dbp = NULL;
if (openinfo) {
if (openinfo->flags & ~(R_FIXEDLEN | R_NOKEY | R_SNAPSHOT))
goto einval;
btopeninfo.flags = 0;
btopeninfo.cachesize = openinfo->cachesize;
btopeninfo.maxkeypage = 0;
btopeninfo.minkeypage = 0;
btopeninfo.psize = openinfo->psize;
btopeninfo.compare = NULL;
btopeninfo.prefix = NULL;
btopeninfo.lorder = openinfo->lorder;
dbp = __bt_open(openinfo->bfname,
O_RDWR, S_IRUSR | S_IWUSR, &btopeninfo, dflags);
} else
dbp = __bt_open(NULL, O_RDWR, S_IRUSR | S_IWUSR, NULL, dflags);
if (dbp == NULL)
goto err;
/*
* Some fields in the tree structure are recno specific. Fill them
* in and make the btree structure look like a recno structure. We
* don't change the bt_ovflsize value, it's close enough and slightly
* bigger.
*/
t = dbp->internal;
if (openinfo) {
if (openinfo->flags & R_FIXEDLEN) {
F_SET(t, R_FIXLEN);
t->bt_reclen = openinfo->reclen;
if (t->bt_reclen == 0)
goto einval;
}
t->bt_bval = openinfo->bval;
} else
t->bt_bval = '\n';
F_SET(t, R_RECNO);
if (fname == NULL)
F_SET(t, R_EOF | R_INMEM);
else
t->bt_rfd = rfd;
if (fname != NULL) {
/*
* In 4.4BSD, stat(2) returns true for ISSOCK on pipes.
* Unfortunately, that's not portable, so we use lseek
* and check the errno values.
*/
errno = 0;
if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) {
switch (flags & O_ACCMODE) {
case O_RDONLY:
F_SET(t, R_RDONLY);
break;
default:
goto einval;
}
slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
goto err;
F_SET(t, R_CLOSEFP);
t->bt_irec =
F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
} else {
switch (flags & O_ACCMODE) {
case O_RDONLY:
F_SET(t, R_RDONLY);
break;
case O_RDWR:
break;
default:
goto einval;
}
if (fstat(rfd, &sb))
goto err;
/*
* Kluge -- we'd like to test to see if the file is too
* big to mmap. Since, we don't know what size or type
* off_t's or size_t's are, what the largest unsigned
* integral type is, or what random insanity the local
* C compiler will perpetrate, doing the comparison in
* a portable way is flatly impossible. Hope that mmap
* fails if the file is too large.
*/
if (sb.st_size == 0)
F_SET(t, R_EOF);
else {
#ifdef MMAP_NOT_AVAILABLE
/*
* XXX
* Mmap doesn't work correctly on many current
* systems. In particular, it can fail subtly,
* with cache coherency problems. Don't use it
* for now.
*/
t->bt_msize = sb.st_size;
if ((t->bt_smap = mmap(NULL, t->bt_msize,
PROT_READ, MAP_PRIVATE, rfd,
(off_t)0)) == (caddr_t)-1)
goto slow;
t->bt_cmap = t->bt_smap;
t->bt_emap = t->bt_smap + sb.st_size;
t->bt_irec = F_ISSET(t, R_FIXLEN) ?
__rec_fmap : __rec_vmap;
F_SET(t, R_MEMMAPPED);
#else
goto slow;
#endif
}
}
}
/* Use the recno routines. */
dbp->close = __rec_close;
dbp->del = __rec_delete;
dbp->fd = __rec_fd;
dbp->get = __rec_get;
dbp->put = __rec_put;
dbp->seq = __rec_seq;
dbp->sync = __rec_sync;
/* If the root page was created, reset the flags. */
if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
goto err;
if ((h->flags & P_TYPE) == P_BLEAF) {
F_CLR(h, P_TYPE);
F_SET(h, P_RLEAF);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
} else
mpool_put(t->bt_mp, h, 0);
if (openinfo && openinfo->flags & R_SNAPSHOT &&
!F_ISSET(t, R_EOF | R_INMEM) &&
t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
goto err;
return (dbp);
einval: errno = EINVAL;
err: sverrno = errno;
if (dbp != NULL)
(void)__bt_close(dbp);
if (fname != NULL)
(void)close(rfd);
errno = sverrno;
return (NULL);
}
int
__rec_fd(dbp)
const DB *dbp;
{
BTREE *t;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/* In-memory database can't have a file descriptor. */
if (F_ISSET(t, R_INMEM)) {
errno = ENOENT;
return (-1);
}
return (t->bt_rfd);
}
+280
View File
@@ -0,0 +1,280 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_put.c 8.7 (Berkeley) 8/18/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "recno.h"
/*
* __REC_PUT -- Add a recno item to the tree.
*
* Parameters:
* dbp: pointer to access method
* key: key
* data: data
* flag: R_CURSOR, R_IAFTER, R_IBEFORE, R_NOOVERWRITE
*
* Returns:
* RET_ERROR, RET_SUCCESS and RET_SPECIAL if the key is
* already in the tree and R_NOOVERWRITE specified.
*/
int
__rec_put(dbp, key, data, flags)
const DB *dbp;
DBT *key;
const DBT *data;
u_int flags;
{
BTREE *t;
DBT fdata, tdata;
recno_t nrec;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
/*
* If using fixed-length records, and the record is long, return
* EINVAL. If it's short, pad it out. Use the record data return
* memory, it's only short-term.
*/
if (F_ISSET(t, R_FIXLEN) && data->size != t->bt_reclen) {
if (data->size > t->bt_reclen)
goto einval;
if (t->bt_rdata.size < t->bt_reclen) {
t->bt_rdata.data = t->bt_rdata.data == NULL ?
malloc(t->bt_reclen) :
realloc(t->bt_rdata.data, t->bt_reclen);
if (t->bt_rdata.data == NULL)
return (RET_ERROR);
t->bt_rdata.size = t->bt_reclen;
}
memmove(t->bt_rdata.data, data->data, data->size);
memset((char *)t->bt_rdata.data + data->size,
t->bt_bval, t->bt_reclen - data->size);
fdata.data = t->bt_rdata.data;
fdata.size = t->bt_reclen;
} else {
fdata.data = data->data;
fdata.size = data->size;
}
switch (flags) {
case R_CURSOR:
if (!F_ISSET(&t->bt_cursor, CURS_INIT))
goto einval;
nrec = t->bt_cursor.rcursor;
break;
case R_SETCURSOR:
if ((nrec = *(recno_t *)key->data) == 0)
goto einval;
break;
case R_IAFTER:
if ((nrec = *(recno_t *)key->data) == 0) {
nrec = 1;
flags = R_IBEFORE;
}
break;
case 0:
case R_IBEFORE:
if ((nrec = *(recno_t *)key->data) == 0)
goto einval;
break;
case R_NOOVERWRITE:
if ((nrec = *(recno_t *)key->data) == 0)
goto einval;
if (nrec <= t->bt_nrecs)
return (RET_SPECIAL);
break;
default:
einval: errno = EINVAL;
return (RET_ERROR);
}
/*
* Make sure that records up to and including the put record are
* already in the database. If skipping records, create empty ones.
*/
if (nrec > t->bt_nrecs) {
if (!F_ISSET(t, R_EOF | R_INMEM) &&
t->bt_irec(t, nrec) == RET_ERROR)
return (RET_ERROR);
if (nrec > t->bt_nrecs + 1) {
if (F_ISSET(t, R_FIXLEN)) {
if ((tdata.data =
(void *)malloc(t->bt_reclen)) == NULL)
return (RET_ERROR);
tdata.size = t->bt_reclen;
memset(tdata.data, t->bt_bval, tdata.size);
} else {
tdata.data = NULL;
tdata.size = 0;
}
while (nrec > t->bt_nrecs + 1)
if (__rec_iput(t,
t->bt_nrecs, &tdata, 0) != RET_SUCCESS)
return (RET_ERROR);
if (F_ISSET(t, R_FIXLEN))
free(tdata.data);
}
}
if ((status = __rec_iput(t, nrec - 1, &fdata, flags)) != RET_SUCCESS)
return (status);
if (flags == R_SETCURSOR)
t->bt_cursor.rcursor = nrec;
F_SET(t, R_MODIFIED);
return (__rec_ret(t, NULL, nrec, key, NULL));
}
/*
* __REC_IPUT -- Add a recno item to the tree.
*
* Parameters:
* t: tree
* nrec: record number
* data: data
*
* Returns:
* RET_ERROR, RET_SUCCESS
*/
int
__rec_iput(t, nrec, data, flags)
BTREE *t;
recno_t nrec;
const DBT *data;
u_int flags;
{
DBT tdata;
EPG *e;
PAGE *h;
indx_t index, nxtindex;
pgno_t pg;
u_int32_t nbytes;
int dflags, status;
char *dest, db[NOVFLSIZE];
/*
* If the data won't fit on a page, store it on indirect pages.
*
* XXX
* If the insert fails later on, these pages aren't recovered.
*/
if (data->size > t->bt_ovflsize) {
if (__ovfl_put(t, data, &pg) == RET_ERROR)
return (RET_ERROR);
tdata.data = db;
tdata.size = NOVFLSIZE;
*(pgno_t *)db = pg;
*(u_int32_t *)(db + sizeof(pgno_t)) = data->size;
dflags = P_BIGDATA;
data = &tdata;
} else
dflags = 0;
/* __rec_search pins the returned page. */
if ((e = __rec_search(t, nrec,
nrec > t->bt_nrecs || flags == R_IAFTER || flags == R_IBEFORE ?
SINSERT : SEARCH)) == NULL)
return (RET_ERROR);
h = e->page;
index = e->index;
/*
* Add the specified key/data pair to the tree. The R_IAFTER and
* R_IBEFORE flags insert the key after/before the specified key.
*
* Pages are split as required.
*/
switch (flags) {
case R_IAFTER:
++index;
break;
case R_IBEFORE:
break;
default:
if (nrec < t->bt_nrecs &&
__rec_dleaf(t, h, index) == RET_ERROR) {
mpool_put(t->bt_mp, h, 0);
return (RET_ERROR);
}
break;
}
/*
* If not enough room, split the page. The split code will insert
* the key and data and unpin the current page. If inserting into
* the offset array, shift the pointers up.
*/
nbytes = NRLEAFDBT(data->size);
if (h->upper - h->lower < nbytes + sizeof(indx_t)) {
status = __bt_split(t, h, NULL, data, dflags, nbytes, index);
if (status == RET_SUCCESS)
++t->bt_nrecs;
return (status);
}
if (index < (nxtindex = NEXTINDEX(h)))
memmove(h->linp + index + 1, h->linp + index,
(nxtindex - index) * sizeof(indx_t));
h->lower += sizeof(indx_t);
h->linp[index] = h->upper -= nbytes;
dest = (char *)h + h->upper;
WR_RLEAF(dest, data, dflags);
++t->bt_nrecs;
F_SET(t, B_MODIFIED);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
return (RET_SUCCESS);
}
+126
View File
@@ -0,0 +1,126 @@
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_search.c 8.4 (Berkeley) 7/14/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <db.h>
#include "recno.h"
/*
* __REC_SEARCH -- Search a btree for a key.
*
* Parameters:
* t: tree to search
* recno: key to find
* op: search operation
*
* Returns:
* EPG for matching record, if any, or the EPG for the location of the
* key, if it were inserted into the tree.
*
* Returns:
* The EPG for matching record, if any, or the EPG for the location
* of the key, if it were inserted into the tree, is entered into
* the bt_cur field of the tree. A pointer to the field is returned.
*/
EPG *
__rec_search(t, recno, op)
BTREE *t;
recno_t recno;
enum SRCHOP op;
{
register indx_t index;
register PAGE *h;
EPGNO *parent;
RINTERNAL *r;
pgno_t pg;
indx_t top;
recno_t total;
int sverrno;
BT_CLR(t);
for (pg = P_ROOT, total = 0;;) {
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
goto err;
if (h->flags & P_RLEAF) {
t->bt_cur.page = h;
t->bt_cur.index = recno - total;
return (&t->bt_cur);
}
for (index = 0, top = NEXTINDEX(h);;) {
r = GETRINTERNAL(h, index);
if (++index == top || total + r->nrecs > recno)
break;
total += r->nrecs;
}
BT_PUSH(t, pg, index - 1);
pg = r->pgno;
switch (op) {
case SDELETE:
--GETRINTERNAL(h, (index - 1))->nrecs;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
break;
case SINSERT:
++GETRINTERNAL(h, (index - 1))->nrecs;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
break;
case SEARCH:
mpool_put(t->bt_mp, h, 0);
break;
}
}
/* Try and recover the tree. */
err: sverrno = errno;
if (op != SEARCH)
while ((parent = BT_POP(t)) != NULL) {
if ((h = mpool_get(t->bt_mp, parent->pgno, 0)) == NULL)
break;
if (op == SINSERT)
--GETRINTERNAL(h, parent->index)->nrecs;
else
++GETRINTERNAL(h, parent->index)->nrecs;
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
}
errno = sverrno;
return (NULL);
}
+131
View File
@@ -0,0 +1,131 @@
/*-
* Copyright (c) 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94";
#endif /* not lint */
#include <sys/types.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <db.h>
#include "recno.h"
/*
* __REC_SEQ -- Recno sequential scan interface.
*
* Parameters:
* dbp: pointer to access method
* key: key for positioning and return value
* data: data return value
* flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
int
__rec_seq(dbp, key, data, flags)
const DB *dbp;
DBT *key, *data;
u_int flags;
{
BTREE *t;
EPG *e;
recno_t nrec;
int status;
t = dbp->internal;
/* Toss any page pinned across calls. */
if (t->bt_pinned != NULL) {
mpool_put(t->bt_mp, t->bt_pinned, 0);
t->bt_pinned = NULL;
}
switch(flags) {
case R_CURSOR:
if ((nrec = *(recno_t *)key->data) == 0)
goto einval;
break;
case R_NEXT:
if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
nrec = t->bt_cursor.rcursor + 1;
break;
}
/* FALLTHROUGH */
case R_FIRST:
nrec = 1;
break;
case R_PREV:
if (F_ISSET(&t->bt_cursor, CURS_INIT)) {
if ((nrec = t->bt_cursor.rcursor - 1) == 0)
return (RET_SPECIAL);
break;
}
/* FALLTHROUGH */
case R_LAST:
if (!F_ISSET(t, R_EOF | R_INMEM) &&
t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
return (RET_ERROR);
nrec = t->bt_nrecs;
break;
default:
einval: errno = EINVAL;
return (RET_ERROR);
}
if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
if (!F_ISSET(t, R_EOF | R_INMEM) &&
(status = t->bt_irec(t, nrec)) != RET_SUCCESS)
return (status);
if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
return (RET_SPECIAL);
}
if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
return (RET_ERROR);
F_SET(&t->bt_cursor, CURS_INIT);
t->bt_cursor.rcursor = nrec;
status = __rec_ret(t, e, nrec, key, data);
if (F_ISSET(t, B_DB_LOCK))
mpool_put(t->bt_mp, e->page, 0);
else
t->bt_pinned = e->page;
return (status);
}
+122
View File
@@ -0,0 +1,122 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rec_utils.c 8.6 (Berkeley) 7/16/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <db.h>
#include "recno.h"
/*
* __rec_ret --
* Build return data.
*
* Parameters:
* t: tree
* e: key/data pair to be returned
* nrec: record number
* key: user's key structure
* data: user's data structure
*
* Returns:
* RET_SUCCESS, RET_ERROR.
*/
int
__rec_ret(t, e, nrec, key, data)
BTREE *t;
EPG *e;
recno_t nrec;
DBT *key, *data;
{
RLEAF *rl;
void *p;
if (key == NULL)
goto dataonly;
/* We have to copy the key, it's not on the page. */
if (sizeof(recno_t) > t->bt_rkey.size) {
p = (void *)(t->bt_rkey.data == NULL ?
malloc(sizeof(recno_t)) :
realloc(t->bt_rkey.data, sizeof(recno_t)));
if (p == NULL)
return (RET_ERROR);
t->bt_rkey.data = p;
t->bt_rkey.size = sizeof(recno_t);
}
memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
key->size = sizeof(recno_t);
key->data = t->bt_rkey.data;
dataonly:
if (data == NULL)
return (RET_SUCCESS);
/*
* We must copy big keys/data to make them contigous. Otherwise,
* leave the page pinned and don't copy unless the user specified
* concurrent access.
*/
rl = GETRLEAF(e->page, e->index);
if (rl->flags & P_BIGDATA) {
if (__ovfl_get(t, rl->bytes,
&data->size, &t->bt_rdata.data, &t->bt_rdata.size))
return (RET_ERROR);
data->data = t->bt_rdata.data;
} else if (F_ISSET(t, B_DB_LOCK)) {
/* Use +1 in case the first record retrieved is 0 length. */
if (rl->dsize + 1 > t->bt_rdata.size) {
p = (void *)(t->bt_rdata.data == NULL ?
malloc(rl->dsize + 1) :
realloc(t->bt_rdata.data, rl->dsize + 1));
if (p == NULL)
return (RET_ERROR);
t->bt_rdata.data = p;
t->bt_rdata.size = rl->dsize + 1;
}
memmove(t->bt_rdata.data, rl->bytes, rl->dsize);
data->size = rl->dsize;
data->data = t->bt_rdata.data;
} else {
data->size = rl->dsize;
data->data = rl->bytes;
}
return (RET_SUCCESS);
}
+39
View File
@@ -0,0 +1,39 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)recno.h 8.1 (Berkeley) 6/4/93
*/
enum SRCHOP { SDELETE, SINSERT, SEARCH}; /* Rec_search operation. */
#include "../btree/btree.h"
#include "extern.h"
+3 -3
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -21,11 +21,11 @@
#
subdir := dirent
headers := dirent.h
headers := dirent.h direntry.h
routines := opendir closedir readdir rewinddir \
seekdir telldir scandir alphasort \
getdents dirfd
distribute := direct.h dirstream.h
distribute := dirstream.h
tests := list tst-seekdir
+35 -17
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -29,30 +29,48 @@ __BEGIN_DECLS
#include <gnu/types.h>
/* This file defines `struct dirent'.
/* Directory entry structure.
It defines the macro `_DIRENT_HAVE_D_NAMLEN' iff there is a `d_namlen'
member that gives the length of `d_name'.
This structure is laid out identically to the `struct direct' that
represents directory entries in the GNU Hurd and in BSD 4.4 (and
incidentally, on disk in the Berkeley fast file system). The `readdir'
implementations for GNU and BSD know this; you must change them if you
change this structure. */
It defines the macro `_DIRENT_HAVE_D_RECLEN' iff there is a `d_reclen'
member that gives the size of the entire directory entry. */
struct dirent
{
__ino_t d_fileno; /* File serial number. */
unsigned short int d_reclen; /* Length of the whole `struct dirent'. */
unsigned char d_type; /* File type, possibly unknown. */
unsigned char d_namlen; /* Length of the file name. */
/* Only this member is in the POSIX standard. */
char d_name[1]; /* File name (actually longer). */
};
#include <direntry.h>
#if defined(__USE_BSD) || defined(__USE_MISC)
#define d_ino d_fileno /* Backward compatibility. */
#endif
/* These macros extract size information from a `struct dirent *'.
They may evaluate their argument multiple times, so it must not
have side effects. Each of these may involve a relatively costly
call to `strlen' on some systems, so these values should be cached.
_D_EXACT_NAMLEN (DP) returns the length of DP->d_name, not including
its terminating null character.
_D_ALLOC_NAMLEN (DP) returns a size at least (_D_EXACT_NAMLEN (DP) + 1);
that is, the allocation size needed to hold the DP->d_name string.
Use this macro when you don't need the exact length, just an upper bound.
This macro is less likely to require calling `strlen' than _D_EXACT_NAMLEN.
*/
#ifdef _DIRENT_HAVE_D_NAMLEN
#define _D_EXACT_NAMLEN(d) ((d)->d_namlen)
#define _D_ALLOC_NAMLEN(d) (_D_EXACT_NAMLEN (d) + 1)
#else
#define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name))
#ifdef _DIRENT_HAVE_D_RECLEN
#define _D_ALLOC_NAMLEN(d) (((char *) (d) + (d)->d_reclen) - &(d)->d_name[0])
#else
#define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \
_D_EXACT_NAMLEN (d) + 1)
#endif
#endif
#ifdef __USE_BSD
/* File types for `d_type'. */
enum
+7 -3
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1992, 1993, 1994, 1995, 1996 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
@@ -19,6 +19,7 @@ Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int
@@ -44,6 +45,8 @@ DEFUN(scandir, (dir, namelist, select, cmp),
while ((d = readdir (dp)) != NULL)
if (select == NULL || (*select) (d))
{
size_t dsize;
if (i == vsize)
{
struct dirent **new;
@@ -61,11 +64,12 @@ DEFUN(scandir, (dir, namelist, select, cmp),
v = new;
}
v[i] = (struct dirent *) malloc (sizeof (**v));
dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
v[i] = (struct dirent *) malloc (dsize);
if (v[i] == NULL)
goto lose;
*v[i++] = *d;
memcpy (v[i++], d, dsize);
}
if (errno != 0)
+31 -8
View File
@@ -28,35 +28,58 @@ libelf-routines := elf_hash
libdl-routines := dlopen dlclose dlsym dlerror
libdl-inhibit-o = $(filter-out .so,$(object-suffixes)) # Build only shared.
rtld-routines := rtld $(addprefix dl-,load lookup object reloc \
rtld-routines := rtld $(addprefix dl-,minimal load lookup object reloc \
runtime sysdep error init fini)
distribute = $(rtld-routines:=.c) dynamic-link.h do-rel.h \
soinit.c sofini.c ldd.sh.in
soinit.c sofini.c ldd.sh.in linux-compat.c
all: # Make this the default target; it will be defined in Rules.
include ../Makeconfig
ifeq (yes,$(build-shared))
extra-objs = $(rtld-routines:=.so) soinit.so sofini.so
install-others = $(libdir)/$(rtld-installed-name)
generated = librtld.so
install-others = $(slibdir)/$(rtld-installed-name)
install-bin = ldd
ifneq (,$(filter linux%,$(config-os)))
extra-objs += linux-compat.so
install-others += $(slibdir)/ld-linux.so.1
endif
endif
include ../Rules
$(objpfx)ld.so: $(rtld-routines:%=$(objpfx)%.so) \
$(patsubst %,$(common-objpfx)lib%_pic.a,\
elf c $(LDLIBS-c.so:-l%=%))
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
# Link together the dynamic linker into a single relocatable object.
# We use this to produce both the ABI-compliant and Linux-compatible
# dynamic linker shared objects below.
$(objpfx)librtld.so: $(rtld-routines:%=$(objpfx)%.so) \
$(patsubst %,$(common-objpfx)lib%_pic.a,\
elf c $(LDLIBS-c.so:-l%=%))
$(LINK.o) -nostdlib -nostartfiles -r -o $@ \
'-Wl,-(' $^ -lgcc '-Wl,-)'
$(objpfx)ld.so $(objpfx)ld-linux.so.1: $(objpfx)librtld.so
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
-Wl,-rpath=$(default-rpath) $^
# The Linux-compatible dynamic linker shared object is just the same
# with one object file of compatibility initialization code added.
$(objpfx)ld-linux.so.1: $(objpfx)linux-compat.so
$(objpfx)libdl.so: $(objpfx)libdl_pic.a $(common-objpfx)libc.so $(objpfx)ld.so
$(patsubst %/,cd %;,$(objpfx)) \
$(LINK.o) -shared -o $(@:$(objpfx)%=%) \
$(LDFLAGS.so) $(LDFLAGS-dl.so) \
-Wl,--whole-archive $(^:$(objpfx)%=%)
$(libdir)$(rtld-installed-name): $(objpfx)ld.so; $(do-install-program)
$(slibdir)/$(rtld-installed-name): $(objpfx)ld.so; $(do-install-program)
$(slibdir)/ld-linux.so.1: $(objpfx)ld-linux.so.1; $(do-install-program)
$(objpfx)ldd: ldd.sh.in
sed 's%@RTLD@%$(libdir)/$(rtld-installed-name)%g' < $< > $@.new
chmod 555 $@.new
mv -f $@.new $@
+3 -2
View File
@@ -62,7 +62,8 @@ _dl_init_next (void)
}
}
if (l->l_info[DT_INIT])
if (l->l_info[DT_INIT] &&
!(l->l_name[0] == '\0' && l->l_type == lt_executable))
{
/* Run this object's initializer. */
l->l_init_running = 1;
@@ -76,7 +77,7 @@ _dl_init_next (void)
}
/* Look for the first initializer not yet called. */
l = _dl_loaded->l_next; /* Skip the executable itself. */
l = _dl_loaded;
do
{
init = next_init (l);
+54 -19
View File
@@ -1,5 +1,5 @@
/* _dl_map_object -- Map in a shared object's segments from the file.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 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
@@ -28,6 +28,23 @@ Cambridge, MA 02139, USA. */
#include "dynamic-link.h"
/* On some systems, no flag bits are given to specify file mapping. */
#ifndef MAP_FILE
#define MAP_FILE 0
#endif
/* The right way to map in the shared library files is MAP_COPY, which
makes a virtual copy of the data at the time of the mmap call; this
guarantees the mapped pages will be consistent even if the file is
overwritten. Some losing VM systems like Linux's lack MAP_COPY. All we
get is MAP_PRIVATE, which copies each page when it is modified; this
means if the file is overwritten, we may at some point get some pages
from the new version after starting with pages from the old version. */
#ifndef MAP_COPY
#define MAP_COPY MAP_PRIVATE
#endif
#include <endian.h>
#if BYTE_ORDER == BIG_ENDIAN
#define byteorder ELFDATA2MSB
@@ -139,7 +156,10 @@ _dl_map_object (struct link_map *loader, const char *name)
if (fd == -1 && ! _dl_secure)
trypath (getenv ("LD_LIBRARY_PATH"));
if (fd == -1)
trypath ("/lib:/usr/lib");
{
extern const char *_dl_rpath; /* Set in rtld.c. */
trypath (_dl_rpath);
}
}
else
{
@@ -179,7 +199,7 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
int prot, int fixed, off_t offset)
{
caddr_t mapat = mmap ((caddr_t) mapstart, len, prot,
fixed|MAP_COPY|MAP_FILE|MAP_INHERIT,
fixed|MAP_COPY|MAP_FILE,
fd, offset);
if (mapat == (caddr_t) -1)
lose (errno, "failed to map segment from shared object");
@@ -226,10 +246,19 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
header = map (0, sizeof *header);
/* Check the header for basic validity. */
if (*(Elf32_Word *) &header->e_ident != ((ELFMAG0 << (EI_MAG0 * 8)) |
(ELFMAG1 << (EI_MAG1 * 8)) |
(ELFMAG2 << (EI_MAG2 * 8)) |
(ELFMAG3 << (EI_MAG3 * 8))))
if (*(Elf32_Word *) &header->e_ident !=
#if BYTE_ORDER == LITTLE_ENDIAN
((ELFMAG0 << (EI_MAG0 * 8)) |
(ELFMAG1 << (EI_MAG1 * 8)) |
(ELFMAG2 << (EI_MAG2 * 8)) |
(ELFMAG3 << (EI_MAG3 * 8)))
#else
((ELFMAG0 << (EI_MAG3 * 8)) |
(ELFMAG1 << (EI_MAG2 * 8)) |
(ELFMAG2 << (EI_MAG1 * 8)) |
(ELFMAG3 << (EI_MAG0 * 8)))
#endif
)
LOSE ("invalid ELF header");
if (header->e_ident[EI_CLASS] != ELFCLASS32)
LOSE ("ELF file class not 32-bit");
@@ -298,8 +327,8 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
{
struct loadcmd *c = &loadcmds[nloadcmds++];
c->mapstart = ph->p_vaddr & ~(ph->p_align - 1);
c->mapend = ((ph->p_vaddr + ph->p_filesz + ph->p_align - 1)
& ~(ph->p_align - 1));
c->mapend = ((ph->p_vaddr + ph->p_filesz + pagesize - 1)
& ~(pagesize - 1));
c->dataend = ph->p_vaddr + ph->p_filesz;
c->allocend = ph->p_vaddr + ph->p_memsz;
c->mapoff = ph->p_offset & ~(ph->p_align - 1);
@@ -326,20 +355,23 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
kernel map it anywhere it likes, but we must have space for all
the segments in their specified positions relative to the first.
So we map the first segment without MAP_FIXED, but with its
extent increased to cover all the segments. Then we unmap the
excess portion, and there is known sufficient space there to map
the later segments. */
extent increased to cover all the segments. Then we remove
access from excess portion, and there is known sufficient space
there to remap from the later segments. */
caddr_t mapat;
mapat = map_segment (c->mapstart,
loadcmds[nloadcmds - 1].allocend - c->mapstart,
c->prot, 0, c->mapoff);
l->l_addr = (Elf32_Addr) mapat - c->mapstart;
/* Unmap the excess portion, and then jump into the normal
segment-mapping loop to handle the portion of the segment past
the end of the file mapping. */
munmap (mapat + c->mapend,
loadcmds[nloadcmds - 1].allocend - c->mapend);
/* Change protection on the excess portion to disallow all access;
the portions we do not remap later will be inaccessible as if
unallocated. Then jump into the normal segment-mapping loop to
handle the portion of the segment past the end of the file
mapping. */
mprotect (mapat + c->mapend,
loadcmds[nloadcmds - 1].allocend - c->mapend,
0);
goto postmap;
}
@@ -387,10 +419,10 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
/* Map the remaining zero pages in from the zero fill FD. */
caddr_t mapat;
mapat = mmap ((caddr_t) zeropage, zeroend - zeropage, c->prot,
MAP_ANON|MAP_PRIVATE|MAP_FIXED|MAP_INHERIT,
MAP_ANON|MAP_PRIVATE|MAP_FIXED,
_dl_zerofd, 0);
if (mapat == (caddr_t) -1)
lose (errno, "cannot map zero pages");
lose (errno, "cannot map zero-fill pages");
}
}
@@ -398,6 +430,9 @@ _dl_map_object_from_fd (const char *name, int fd, char *realname)
}
}
if (type == ET_EXEC)
l->l_type = lt_executable;
if (l->l_ld == 0)
{
if (type == ET_DYN)
+2 -2
View File
@@ -22,7 +22,7 @@ Cambridge, MA 02139, USA. */
#include <link.h>
#include <assert.h>
/* Search loaded objects' symbol tables for a definition of
/* Search loaded objects' symbol tables for a definition of
the symbol UNDEF_NAME. If NOSELF is nonzero, then *REF
cannot satisfy the reference itself; some different binding
must be found. */
@@ -100,7 +100,7 @@ _dl_lookup_symbol (const char *undef_name, const Elf32_Sym **ref,
}
}
if (weak_value.s == NULL)
if (weak_value.s == NULL && ELF32_ST_BIND ((*ref)->st_info) != STB_WEAK)
{
const char msg[] = "undefined symbol: ";
char buf[sizeof msg + strlen (undef_name)];
+154
View File
@@ -0,0 +1,154 @@
/* Minimal replacements for basic facilities used in the dynamic linker.
Copyright (C) 1995 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., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <sys/types.h>
#include <sys/mman.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <link.h>
#include "../stdio-common/_itoa.h"
/* Minimal `malloc' allocator for use while loading shared libraries.
Only small blocks are allocated, and none are ever freed. */
static void *alloc_ptr, *alloc_end, *alloc_last_block;
void *
malloc (size_t n)
{
extern int _dl_zerofd;
static size_t pagesize;
if (pagesize == 0)
pagesize = __getpagesize ();
if (_dl_zerofd == -1)
_dl_zerofd = _dl_sysdep_open_zero_fill ();
if (alloc_end == 0)
{
/* Consume any unused space in the last page of our data segment. */
extern int _end;
alloc_ptr = &_end;
alloc_end = (void *) 0 + (((alloc_ptr - (void *) 0) + pagesize - 1)
& ~(pagesize - 1));
}
/* Make sure the allocation pointer is ideally aligned. */
alloc_ptr = (void *) 0 + (((alloc_ptr - (void *) 0) + sizeof (double) - 1)
& ~(sizeof (double) - 1));
if (alloc_ptr + n >= alloc_end)
{
/* Insufficient space left; allocate another page. */
caddr_t page;
assert (n <= pagesize);
page = mmap (0, pagesize, PROT_READ|PROT_WRITE,
MAP_ANON|MAP_PRIVATE, _dl_zerofd, 0);
assert (page != (caddr_t) -1);
if (page != alloc_end)
alloc_ptr = page;
alloc_end = page + pagesize;
}
alloc_last_block = (void *) alloc_ptr;
alloc_ptr += n;
return alloc_last_block;
}
weak_symbol (malloc)
/* This will rarely be called. */
void
free (void *ptr)
{
/* We can free only the last block allocated. */
if (ptr == alloc_last_block)
alloc_ptr = alloc_last_block;
}
weak_symbol (free)
/* This is never called. */
void *
realloc (void *ptr, size_t n)
{ ptr += n; abort (); }
weak_symbol (realloc)
/* Avoid signal frobnication in setjmp/longjmp. Keeps things smaller. */
#include <setjmp.h>
int __sigjmp_save (sigjmp_buf env, int savemask)
{ env[0].__mask_was_saved = savemask; return 0; }
weak_symbol (__sigjmp_save)
void
longjmp (jmp_buf env, int val) { __longjmp (env[0].__jmpbuf, val); }
weak_symbol (longjmp)
/* Define our own stub for the localization function used by strerror.
English-only in the dynamic linker keeps it smaller. */
char *
__dgettext (const char *domainname, const char *msgid)
{
assert (domainname == _libc_intl_domainname);
return (char *) msgid;
}
weak_symbol (__dgettext)
weak_alias (__dgettext, dgettext)
#ifndef NDEBUG
/* Define (weakly) our own assert failure function which doesn't use stdio.
If we are linked into the user program (-ldl), the normal __assert_fail
defn can override this one. */
void
__assert_fail (const char *assertion,
const char *file, unsigned int line, const char *function)
{
char buf[64];
buf[sizeof buf - 1] = '\0';
_dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
file, ": ", _itoa (line, buf + sizeof buf - 1, 10, 0),
": ", function ?: "", function ? ": " : "",
"Assertion `", assertion, "' failed!\n",
NULL);
}
weak_symbol (__assert_fail)
void
__assert_perror_fail (int errnum,
const char *file, unsigned int line,
const char *function)
{
char buf[64];
buf[sizeof buf - 1] = '\0';
_dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
file, ": ", _itoa (line, buf + sizeof buf - 1, 10, 0),
": ", function ?: "", function ? ": " : "",
"Unexpected error: ", strerror (errnum), "\n", NULL);
}
weak_symbol (__assert_perror_fail)
#endif
+4 -5
View File
@@ -1,5 +1,5 @@
/* Relocate a shared object and resolve its references to other loaded objects.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 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
@@ -93,10 +93,9 @@ _dl_relocate_object (struct link_map *l, int lazy)
l->l_prev->l_next = l;
}
if (l->l_info[DT_JMPREL] && lazy)
/* Set up the PLT so its unrelocated entries will
jump to _dl_runtime_resolve, which will relocate them. */
elf_machine_runtime_setup (l);
/* Set up the PLT so its unrelocated entries will
jump to _dl_runtime_resolve, which will relocate them. */
elf_machine_runtime_setup (l, lazy);
l->l_relocated = 1;
+108
View File
@@ -0,0 +1,108 @@
/* On-demand PLT fixup for shared objects.
Copyright (C) 1995, 1996 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., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <link.h>
#include "dynamic-link.h"
/* Figure out the right type, Rel or Rela. */
#define elf_machine_rel 1
#define elf_machine_rela 2
#if elf_machine_relplt == elf_machine_rel
#define PLTREL Elf32_Rel
#elif elf_machine_relplt == elf_machine_rela
#define PLTREL Elf32_Rela
#else
#error "dl-machine.h bug: elf_machine_relplt not rel or rela"
#endif
#undef elf_machine_rel
#undef elf_machine_rela
/* We need to define the function as a local symbol so that the reference
in the trampoline code will be a local PC-relative call. Tell the
compiler not to worry that the function appears not to be called. */
static Elf32_Addr fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
#endif
struct link_map *l, Elf32_Word reloc_offset)
__attribute__ ((unused));
/* This function is called through a special trampoline from the PLT the
first time each PLT entry is called. We must perform the relocation
specified in the PLT of the given shared object, and return the resolved
function address to the trampoline, which will restart the original call
to that address. Future calls will bounce directly from the PLT to the
function. */
static Elf32_Addr
fixup (
#ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
#endif
struct link_map *l, Elf32_Word reloc_offset)
{
const Elf32_Sym *const symtab
= (const Elf32_Sym *) (l->l_addr + l->l_info[DT_SYMTAB]->d_un.d_ptr);
const char *strtab =
(const char *) (l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr);
const PLTREL *const reloc
= (const void *) (l->l_addr + l->l_info[DT_JMPREL]->d_un.d_ptr +
reloc_offset);
const Elf32_Sym *definer;
Elf32_Addr loadbase;
struct link_map *scope, *real_next;
/* Look up the symbol's run-time value. */
real_next = l->l_next;
if (l->l_info[DT_SYMBOLIC])
{
l->l_next = _dl_loaded;
if (l->l_prev)
l->l_prev->l_next = real_next;
scope = l;
}
else
scope = _dl_loaded;
definer = &symtab[ELF32_R_SYM (reloc->r_info)];
loadbase = _dl_lookup_symbol (strtab + definer->st_name, &definer,
scope, l->l_name, 0);
/* Restore list frobnication done above for DT_SYMBOLIC. */
l->l_next = real_next;
if (l->l_prev)
l->l_prev->l_next = l;
/* Apply the relocation with that value. */
elf_machine_relplt (l, reloc, loadbase, definer);
return *(Elf32_Addr *) (l->l_addr + reloc->r_offset);
}
/* This macro is defined in dl-machine.h to define the entry point called
by the PLT. The `fixup' function above does the real work, but a little
more twiddling is needed to get the stack right and jump to the address
finally resolved. */
ELF_MACHINE_RUNTIME_TRAMPOLINE
+4 -4
View File
@@ -28,12 +28,12 @@ dlsym (void *handle, const char *name)
{
struct link_map *map = handle;
struct link_map *real_next;
Elf32_Addr value;
Elf32_Addr loadbase;
const Elf32_Sym *ref = NULL;
int lose;
void doit (void)
{
const Elf32_Sym *ref = NULL;
value = _dl_lookup_symbol (name, &ref, map, map->l_name, 1);
loadbase = _dl_lookup_symbol (name, &ref, map, map->l_name, 1);
}
/* Confine the symbol scope to just this map. */
@@ -42,5 +42,5 @@ dlsym (void *handle, const char *name)
lose = _dlerror_run (doit);
map->l_next = real_next;
return lose ? NULL : (void *) value;
return lose ? NULL : (void *) (loadbase + ref->st_value);
}
+5 -2
View File
@@ -1,5 +1,5 @@
/* Do relocations for ELF dynamic linking.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 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
@@ -36,7 +36,7 @@ Cambridge, MA 02139, USA. */
static inline void
elf_dynamic_do_rel (struct link_map *map,
int reltag, int sztag,
int reltag, int sztag,
Elf32_Addr (*resolve) (const Elf32_Sym **symbol,
Elf32_Addr r_offset),
int lazy)
@@ -59,6 +59,9 @@ elf_dynamic_do_rel (struct link_map *map,
if (ELF32_R_SYM (r->r_info) == STN_UNDEF)
loadbase = 0; /* This value will not be consulted. */
else if (ELF32_ST_BIND (definer->st_info) == STB_LOCAL)
/* Local symbols always refer to the containing object. */
loadbase = map->l_addr;
else
{
if (resolve)
+16 -8
View File
@@ -1,5 +1,5 @@
/* Inline functions for dynamic linking.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 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
@@ -25,11 +25,11 @@ Cambridge, MA 02139, USA. */
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
static inline void
elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM + DT_PROCNUM])
{
unsigned int i;
for (i = 0; i < DT_NUM; ++i)
for (i = 0; i < DT_NUM + DT_PROCNUM; ++i)
info[i] = NULL;
if (! dyn)
@@ -37,8 +37,14 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
while (dyn->d_tag != DT_NULL)
{
assert (dyn->d_tag < DT_NUM);
info[dyn->d_tag] = dyn++;
if (dyn->d_tag < DT_NUM)
info[dyn->d_tag] = dyn;
else if (dyn->d_tag >= DT_LOPROC &&
dyn->d_tag < DT_LOPROC + DT_PROCNUM)
info[dyn->d_tag - DT_LOPROC + DT_NUM] = dyn;
else
assert (! "bad dynamic tag");
dyn++;
}
if (info[DT_RELA])
@@ -60,10 +66,11 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
#define ELF_DYNAMIC_DO_REL(map, lazy, resolve) \
if ((map)->l_info[DT_REL]) \
elf_dynamic_do_rel ((map), DT_REL, DT_RELSZ, (resolve), 0); \
if ((map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL) \
if ((map)->l_info[DT_PLTREL] && \
(map)->l_info[DT_PLTREL]->d_un.d_val == DT_REL) \
elf_dynamic_do_rel ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
#else
#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do. */
#define ELF_DYNAMIC_DO_REL(map, lazy, resolve) /* Nothing to do. */
#endif
#if ! ELF_MACHINE_NO_RELA
@@ -72,7 +79,8 @@ elf_get_dynamic_info (Elf32_Dyn *dyn, Elf32_Dyn *info[DT_NUM])
#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) \
if ((map)->l_info[DT_RELA]) \
elf_dynamic_do_rela ((map), DT_RELA, DT_RELASZ, (resolve), 0); \
if ((map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA) \
if ((map)->l_info[DT_PLTREL] && \
(map)->l_info[DT_PLTREL]->d_un.d_val == DT_RELA) \
elf_dynamic_do_rela ((map), DT_JMPREL, DT_PLTRELSZ, (resolve), (lazy));
#else
#define ELF_DYNAMIC_DO_RELA(map, lazy, resolve) /* Nothing to do. */
+37 -2
View File
@@ -1,5 +1,5 @@
/* This file defines standard ELF types, structures, and macros.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Contributed by Ian Lance Taylor (ian@cygnus.com).
This file is part of the GNU C Library.
@@ -98,6 +98,7 @@ typedef struct
#define ET_EXEC 2 /* Executable file */
#define ET_DYN 3 /* Shared object file */
#define ET_CORE 4 /* Core file */
#define ET_NUM 5 /* Number of defined types. */
#define ET_LOPROC 0xff00 /* Processor-specific */
#define ET_HIPROC 0xffff /* Processor-specific */
@@ -168,6 +169,7 @@ typedef struct
#define SHT_REL 9 /* Relocation entries, no addends */
#define SHT_SHLIB 10 /* Reserved */
#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
#define SHT_NUM 12 /* Number of defined types. */
#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
#define SHT_LOUSER 0x80000000 /* Start of application-specific */
@@ -207,6 +209,7 @@ typedef struct
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* Weak symbol */
#define STB_NUM 3 /* Number of defined types. */
#define STB_LOPROC 13 /* Start of processor-specific */
#define STB_HIPROC 15 /* End of processor-specific */
@@ -217,6 +220,7 @@ typedef struct
#define STT_FUNC 2 /* Symbol is a code object */
#define STT_SECTION 3 /* Symbol associated with a section */
#define STT_FILE 4 /* Symbol's name is file name */
#define STT_NUM 5 /* Number of defined types. */
#define STT_LOPROC 13 /* Start of processor-specific */
#define STT_HIPROC 15 /* End of processor-specific */
@@ -273,6 +277,7 @@ typedef struct {
#define PT_NOTE 4 /* Auxiliary information */
#define PT_SHLIB 5 /* Reserved */
#define PT_PHDR 6 /* Entry for header table itself */
#define PT_NUM 7 /* Number of defined types. */
#define PT_LOPROC 0x70000000 /* Start of processor-specific */
#define PT_HIPROC 0x7fffffff /* End of processor-specific */
@@ -321,9 +326,10 @@ typedef struct
#define DT_DEBUG 21 /* For debugging; unspecified */
#define DT_TEXTREL 22 /* Reloc might modify .text */
#define DT_JMPREL 23 /* Address of PLT relocs */
#define DT_NUM 24 /* Number used. */
#define DT_NUM 24 /* Number used */
#define DT_LOPROC 0x70000000 /* Start of processor-specific */
#define DT_HIPROC 0x7fffffff /* End of processor-specific */
#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */
/* Standard 64 bit ELF types. */
@@ -433,6 +439,34 @@ typedef struct
#define AT_GID 13 /* Real gid */
#define AT_EGID 14 /* Effective gid */
/* Motorola 68k specific definitions. */
/* m68k relocs. */
#define R_68K_NONE 0 /* No reloc */
#define R_68K_32 1 /* Direct 32 bit */
#define R_68K_16 2 /* Direct 16 bit */
#define R_68K_8 3 /* Direct 8 bit */
#define R_68K_PC32 4 /* PC relative 32 bit */
#define R_68K_PC16 5 /* PC relative 16 bit */
#define R_68K_PC8 6 /* PC relative 8 bit */
#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
#define R_68K_GOT32O 10 /* 32 bit GOT offset */
#define R_68K_GOT16O 11 /* 16 bit GOT offset */
#define R_68K_GOT8O 12 /* 8 bit GOT offset */
#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
#define R_68K_PLT32O 16 /* 32 bit PLT offset */
#define R_68K_PLT16O 17 /* 16 bit PLT offset */
#define R_68K_PLT8O 18 /* 8 bit PLT offset */
#define R_68K_COPY 19 /* Copy symbol at runtime */
#define R_68K_GLOB_DAT 20 /* Create GOT entry */
#define R_68K_JMP_SLOT 21 /* Create PLT entry */
#define R_68K_RELATIVE 22 /* Adjust by program base */
/* Intel 80386 specific definitions. */
/* i386 relocs. */
@@ -568,6 +602,7 @@ typedef struct
#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */
#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
#define DT_MIPS_NUM 0x15
/* Legal values for DT_MIPS_FLAG Elf32_Dyn entry. */
+6 -3
View File
@@ -1,5 +1,5 @@
/* Run-time dynamic linker data structures for loaded ELF shared objects.
Copyright (C) 1995 Free Software Foundation, Inc.
Copyright (C) 1995, 1996 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
@@ -82,7 +82,10 @@ struct link_map
They may change without notice. */
const char *l_libname; /* Name requested (before search). */
Elf32_Dyn *l_info[DT_NUM]; /* Indexed pointers to dynamic section. */
/* Indexed pointers to dynamic section.
[0,DT_NUM) are indexed by the processor-independent tags.
[DT_NUM,DT_NUM+DT_PROCNUM] are indexed by the tag minus DT_LOPROC. */
Elf32_Dyn *l_info[DT_NUM + DT_PROCNUM];
const Elf32_Phdr *l_phdr; /* Pointer to program header table in core. */
Elf32_Word l_phnum; /* Number of program header entries. */
Elf32_Addr l_entry; /* Entry point location. */
@@ -141,7 +144,7 @@ extern int _dl_secure;
zero; OBJECT is the name of the problematical shared object, or null if
it is a general problem; ERRSTRING is a string describing the specific
problem. */
extern void _dl_signal_error (int errcode,
const char *object,
const char *errstring)
+40
View File
@@ -0,0 +1,40 @@
/* Initializer for Linux-compatible dynamic linker `/lib/ld-linux.so.1'.
Copyright (C) 1995 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., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <link.h>
#include <stdlib.h>
/* This function will be the DT_INIT initializer for the ld-linux.so.1
shared object. This is called from rtld.c before shlib initializers.
The old Linux ELF startup code expects the dynamic linker to magically
call atexit to arrange for shared object finalizers to run. (The
ABI-compliant startup code does this itself.) We build a compatible
version of the dynamic linker to install as /lib/ld-linux.so.1, the
name old Linux ELF binaries use. */
void
_init (void)
{
const Elf32_Sym *ref = NULL;
Elf32_Addr loadbase = _dl_lookup_symbol ("atexit", &ref, _dl_loaded,
"<ld-linux.so.1 initialization>",
1);
(*(__typeof (atexit) *) (loadbase + ref->st_value)) (&_dl_fini);
}
+121 -87
View File
@@ -22,7 +22,7 @@ Cambridge, MA 02139, USA. */
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include "../stdio/_itoa.h"
#include "../stdio-common/_itoa.h"
#ifdef RTLD_START
@@ -39,10 +39,12 @@ extern Elf32_Addr _dl_sysdep_start (void **start_argptr,
void (*dl_main) (const Elf32_Phdr *phdr,
Elf32_Word phent,
Elf32_Addr *user_entry));
extern void _dl_sysdep_start_cleanup (void);
int _dl_secure;
int _dl_argc;
char **_dl_argv;
const char *_dl_rpath;
struct r_debug dl_r_debug;
@@ -50,22 +52,24 @@ static void dl_main (const Elf32_Phdr *phdr,
Elf32_Word phent,
Elf32_Addr *user_entry);
static struct link_map rtld_map;
Elf32_Addr
_dl_start (void *arg)
{
struct link_map rtld_map;
struct link_map bootstrap_map;
/* Figure out the run-time load address of the dynamic linker itself. */
rtld_map.l_addr = elf_machine_load_address ();
bootstrap_map.l_addr = elf_machine_load_address ();
/* Read our own dynamic section and fill in the info array.
Conveniently, the first element of the GOT contains the
offset of _DYNAMIC relative to the run-time load address. */
rtld_map.l_ld = (void *) rtld_map.l_addr + *elf_machine_got ();
elf_get_dynamic_info (rtld_map.l_ld, rtld_map.l_info);
bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + *elf_machine_got ();
elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_info);
#ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
ELF_MACHINE_BEFORE_RTLD_RELOC (rtld_map.l_info);
ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
#endif
/* Relocate ourselves so we can do normal function calls and
@@ -77,8 +81,8 @@ _dl_start (void *arg)
bootstrapping, so it must anti-perform each bootstrapping relocation
before applying the final relocation when ld.so is linked in as
normal a shared library. */
rtld_map.l_type = lt_library;
ELF_DYNAMIC_RELOCATE (&rtld_map, 0, NULL);
bootstrap_map.l_type = lt_library;
ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, NULL);
/* Now life is sane; we can call functions and access global data.
@@ -86,7 +90,18 @@ _dl_start (void *arg)
the operating system's program loader where to find the program
header table in core. */
dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */
/* Transfer data about ourselves to the permanent link_map structure. */
rtld_map.l_addr = bootstrap_map.l_addr;
rtld_map.l_ld = bootstrap_map.l_ld;
memcpy (rtld_map.l_info, bootstrap_map.l_info, sizeof rtld_map.l_info);
_dl_setup_hash (&rtld_map);
/* Cache the DT_RPATH stored in ld.so itself; this will be
the default search path. */
_dl_rpath = (void *) (rtld_map.l_addr +
rtld_map.l_info[DT_STRTAB]->d_un.d_ptr +
rtld_map.l_info[DT_RPATH]->d_un.d_val);
/* Call the OS-dependent function to set up life so we can do things like
file access. It will call `dl_main' (below) to do all the real work
@@ -111,7 +126,7 @@ dl_main (const Elf32_Phdr *phdr,
void doit (void)
{
const Elf32_Phdr *ph;
struct link_map *l;
struct link_map *l, *last, *before_rtld;
const char *interpreter_name;
int lazy;
int list_only = 0;
@@ -122,9 +137,9 @@ dl_main (const Elf32_Phdr *phdr,
itself! This means someone ran ld.so as a command. Well, that
might be convenient to do sometimes. We support it by
interpreting the args like this:
ld.so PROGRAM ARGS...
The first argument is the name of a file containing an ELF
executable we will load and run with the following arguments.
To simplify life here, PROGRAM is searched for using the
@@ -167,8 +182,7 @@ of this helper program; chances are you did not intend to run this program.\n",
l = _dl_map_object (NULL, _dl_argv[0]);
phdr = l->l_phdr;
phent = l->l_phnum;
l->l_type = lt_executable;
l->l_libname = (char *) "";
l->l_name = (char *) "";
*user_entry = l->l_entry;
}
else
@@ -219,8 +233,9 @@ of this helper program; chances are you did not intend to run this program.\n",
/* Extract the contents of the dynamic section for easy access. */
elf_get_dynamic_info (l->l_ld, l->l_info);
/* Set up our cache of pointers into the hash table. */
_dl_setup_hash (l);
if (l->l_info[DT_HASH])
/* Set up our cache of pointers into the hash table. */
_dl_setup_hash (l);
if (l->l_info[DT_DEBUG])
/* There is a DT_DEBUG entry in the dynamic section. Fill it in
@@ -228,12 +243,19 @@ of this helper program; chances are you did not intend to run this program.\n",
will set up later to communicate with the debugger. */
l->l_info[DT_DEBUG]->d_un.d_ptr = (Elf32_Addr) &dl_r_debug;
l = _dl_new_object ((char *) interpreter_name, interpreter_name,
lt_interpreter);
/* Put the link_map for ourselves on the chain so it can be found by
name. */
rtld_map.l_name = (char *) rtld_map.l_libname = interpreter_name;
rtld_map.l_type = lt_interpreter;
while (l->l_next)
l = l->l_next;
l->l_next = &rtld_map;
rtld_map.l_prev = l;
/* Now process all the DT_NEEDED entries and map in the objects.
Each new link_map will go on the end of the chain, so we will
come across it later in the loop to map in its dependencies. */
before_rtld = NULL;
for (l = _dl_loaded; l; l = l->l_next)
{
if (l->l_info[DT_NEEDED])
@@ -241,27 +263,88 @@ of this helper program; chances are you did not intend to run this program.\n",
const char *strtab
= (void *) l->l_addr + l->l_info[DT_STRTAB]->d_un.d_ptr;
const Elf32_Dyn *d;
last = l;
for (d = l->l_ld; d->d_tag != DT_NULL; ++d)
if (d->d_tag == DT_NEEDED)
_dl_map_object (l, strtab + d->d_un.d_val);
{
struct link_map *new;
new = _dl_map_object (l, strtab + d->d_un.d_val);
new->l_type = lt_library;
if (!before_rtld && new == &rtld_map)
before_rtld = last;
last = new;
}
}
l->l_deps_loaded = 1;
}
l = _dl_loaded->l_next;
while (l->l_type != lt_interpreter)
l = l->l_next;
if (l->l_opencount == 0)
/* If any DT_NEEDED entry referred to the interpreter object itself,
reorder the list so it appears after its dependent. If not,
remove it from the maps we will use for symbol resolution. */
rtld_map.l_prev->l_next = rtld_map.l_next;
if (rtld_map.l_next)
rtld_map.l_next->l_prev = rtld_map.l_prev;
if (before_rtld)
{
/* No DT_NEEDED entry referred to the interpreter object itself.
Remove it from the maps we will use for symbol resolution. */
l->l_prev->l_next = l->l_next;
if (l->l_next)
l->l_next->l_prev = l->l_prev;
rtld_map.l_prev = before_rtld;
rtld_map.l_next = before_rtld->l_next;
before_rtld->l_next = &rtld_map;
if (rtld_map.l_next)
rtld_map.l_next->l_prev = &rtld_map;
}
if (list_only)
{
/* We were run just to list the shared libraries. It is
important that we do this before real relocation, because the
functions we call below for output may no longer work properly
after relocation. */
int i;
if (! _dl_loaded->l_info[DT_NEEDED])
_dl_sysdep_message ("\t", "statically linked\n", NULL);
else
for (l = _dl_loaded->l_next; l; l = l->l_next)
{
char buf[20], *bp;
buf[sizeof buf - 1] = '\0';
bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2)
*--bp = '0';
_dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name,
" (0x", bp, ")\n", NULL);
}
for (i = 1; i < _dl_argc; ++i)
{
const Elf32_Sym *ref = NULL;
Elf32_Addr loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
_dl_loaded, "argument",
1);
char buf[20], *bp;
buf[sizeof buf - 1] = '\0';
bp = _itoa (ref->st_value, &buf[sizeof buf - 1], 16, 0);
while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
*--bp = '0';
_dl_sysdep_message (_dl_argv[i], " found at 0x", bp, NULL);
buf[sizeof buf - 1] = '\0';
bp = _itoa (loadbase, &buf[sizeof buf - 1], 16, 0);
while (&buf[sizeof buf - 1] - bp < sizeof loadbase * 2)
*--bp = '0';
_dl_sysdep_message (" in object at 0x", bp, "\n", NULL);
}
_exit (0);
}
lazy = !_dl_secure && *(getenv ("LD_BIND_NOW") ?: "") == '\0';
/* Do any necessary cleanups for the startup OS interface code.
We do these now so that no calls are made after real relocation
which might be resolved to different functions than we expect. */
_dl_sysdep_start_cleanup ();
/* Now we have all the objects loaded. Relocate them all.
We do this in reverse order so that copy relocs of earlier
objects overwrite the data written by later objects. */
@@ -276,30 +359,21 @@ of this helper program; chances are you did not intend to run this program.\n",
/* Tell the debugger where to find the map of loaded objects. */
dl_r_debug.r_version = 1 /* R_DEBUG_VERSION XXX */;
dl_r_debug.r_ldbase = rtld_map.l_addr; /* Record our load address. */
dl_r_debug.r_map = _dl_loaded;
dl_r_debug.r_brk = (Elf32_Addr) &_dl_r_debug_state;
if (list_only)
if (rtld_map.l_info[DT_INIT])
{
if (! _dl_loaded->l_info[DT_NEEDED])
{
_dl_sysdep_message (_dl_loaded->l_name, ": statically linked\n",
NULL);
_exit (1);
}
/* Call the initializer for the compatibility version of the
dynamic linker. There is no additional initialization
required for the ABI-compliant dynamic linker. */
for (l = _dl_loaded->l_next; l; l = l->l_next)
{
char buf[20], *bp;
buf[sizeof buf - 1] = '\0';
bp = _itoa (l->l_addr, &buf[sizeof buf - 1], 16, 0);
while (&buf[sizeof buf - 1] - bp < sizeof l->l_addr * 2)
*--bp = '0';
_dl_sysdep_message ("\t", l->l_libname, " => ", l->l_name,
" (0x", bp, ")\n", NULL);
}
(*(void (*) (void)) (rtld_map.l_addr +
rtld_map.l_info[DT_INIT]->d_un.d_ptr)) ();
_exit (0);
/* Clear the field so a future dlopen won't run it again. */
rtld_map.l_info[DT_INIT] = NULL;
}
}
const char *errstring;
@@ -318,49 +392,9 @@ of this helper program; chances are you did not intend to run this program.\n",
the DT_INIT functions and then *USER_ENTRY. */
}
/* This function exists solely to have a breakpoint set on it by the
/* This function exists solely to have a breakpoint set on it by the
debugger. */
void
_dl_r_debug_state (void)
{
}
#ifndef NDEBUG
/* Define (weakly) our own assert failure function which doesn't use stdio.
If we are linked into the user program (-ldl), the normal __assert_fail
defn can override this one. */
#include "../stdio/_itoa.h"
void
__assert_fail (const char *assertion,
const char *file, unsigned int line, const char *function)
{
char buf[64];
buf[sizeof buf - 1] = '\0';
_dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
file, ": ", _itoa (line, buf + sizeof buf - 1, 10, 0),
": ", function ?: "", function ? ": " : "",
"Assertion `", assertion, "' failed!\n",
NULL);
}
weak_symbol (__assert_fail)
void
__assert_perror_fail (int errnum,
const char *file, unsigned int line,
const char *function)
{
char buf[64];
buf[sizeof buf - 1] = '\0';
_dl_sysdep_fatal ("BUG IN DYNAMIC LINKER ld.so: ",
file, ": ", _itoa (line, buf + sizeof buf - 1, 10, 0),
": ", function ?: "", function ? ": " : "",
"Unexpected error: ", strerror (errnum), "\n", NULL);
}
weak_symbol (__assert_perror_fail)
#endif
+8 -2
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -37,8 +37,14 @@ __BEGIN_DECLS
#undef __need_Emath
#ifdef _ERRNO_H
/* Declare the `errno' variable. */
/* Declare the `errno' variable, unless it's defined as a macro by
errnos.h. This is the case in GNU, where it is a per-thread variable.
This redeclaration using the macro still works, but it will be a
function declaration without a prototype and may trigger a
-Wstrict-prototypes warning. */
#ifndef errno
extern int errno;
#endif
#ifdef __USE_GNU
/* The full and simple forms of the name with which the program was
+1
View File
@@ -0,0 +1 @@
#include <misc/error.h>
+5 -1
View File
@@ -11,7 +11,7 @@ extra-libs-left := $(filter-out $(lib),$(extra-libs-left))
object-suffixes-$(lib) := $(filter-out $($(lib)-inhibit-o),$(object-suffixes))
# Make sure these are simply-expanded variables before we append to them,
# since we want the expressions we we append to be expanded right now.
# since we want the expressions we append to be expanded right now.
install-lib := $(install-lib)
extra-objs := $(extra-objs)
@@ -25,7 +25,11 @@ ifneq (,$(filter .so,$(object-suffixes-$(lib))))
alltypes-$(lib) += $(objpfx)$(lib).so
endif
ifeq (,$($(lib)-no-lib-dep))
lib-noranlib: $(alltypes-$(lib))
else
others: $(alltypes-$(lib))
endif
# Use o-iterator.mk to generate a rule for each flavor of library.
define o-iterator-doit
+20 -3
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1995 Free Software Foundation, Inc.
# Copyright (C) 1995, 1996 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
@@ -21,8 +21,25 @@
#
subdir := gmon
headers := sys/gmon.h machine-gmon.h
headers := sys/gmon.h
distribute := machine-gmon.h
routines := gmon mcount profil
include ../Rules
# The mcount code won't work without a frame pointer.
CFLAGS-mcount.c := -fno-omit-frame-pointer
# We cannot compile mcount.c with -pg because that would
# create resursive calls. Just copy the normal static object.
# On systems where `profil' is not a system call, the same
# problem exists for the internal functions in profil.c.
noprof := mcount
ifeq (,$(filter profil,$(unix-syscalls)))
noprof += profil
endif
$(noprof:%=$(objpfx)%.po): %.po: %.o
rm -f $@
ln $< $@
+6 -2
View File
@@ -38,6 +38,10 @@ static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93";
#include <sys/param.h>
#include <sys/gmon.h>
/* This file provides the machine-dependent definitions of the _MCOUNT_DECL
and MCOUNT macros. */
#include "machine-gmon.h"
/*
* mcount is called on entry to each function compiled with the profiling
* switch set. _mcount(), which is declared in a machine-dependent way
@@ -48,7 +52,7 @@ static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93";
* _mcount updates data structures that represent traversals of the
* program's call graph edges. frompc and selfpc are the return
* address and function address that represents the given call graph edge.
*
*
* Note: the original BSD code used the same variable (frompcindex) for
* both frompcindex and frompc. Any reasonable, modern compiler will
* perform this optimization.
@@ -154,7 +158,7 @@ _MCOUNT_DECL(frompc, selfpc) /* _mcount; may be static, inline, etc */
*frompcindex = toindex;
goto done;
}
}
done:
#ifdef KERNEL
+16 -5
View File
@@ -36,7 +36,7 @@
#ifndef _SYS_GMON_H_
#define _SYS_GMON_H_
#include <machine-gmon.h>
#include <sys/cdefs.h>
/*
* Structure prepended to gmon.out profiling data file.
@@ -75,7 +75,7 @@ struct gmonhdr {
* calls $0,(r0)
* calls $0,(r0)
*
* which is separated by only three bytes, thus HASHFRACTION is
* which is separated by only three bytes, thus HASHFRACTION is
* calculated as:
*
* HASHFRACTION = 3 / (2 * 2 - 1) = 1
@@ -83,9 +83,9 @@ struct gmonhdr {
* Note that the division above rounds down, thus if MIN_SUBR_FRACTION
* is less than three, this algorithm will not work!
*
* In practice, however, call instructions are rarely at a minimal
* In practice, however, call instructions are rarely at a minimal
* distance. Hence, we will define HASHFRACTION to be 2 across all
* architectures. This saves a reasonable amount of space for
* architectures. This saves a reasonable amount of space for
* profiling data structures without (in practice) sacrificing
* any granularity.
*/
@@ -106,7 +106,7 @@ struct tostruct {
};
/*
* a raw arc, with pointers to the calling site and
* a raw arc, with pointers to the calling site and
* the called site and a count.
*/
struct rawarc {
@@ -156,4 +156,15 @@ extern struct gmonparam _gmonparam;
#define GPROF_FROMS 2 /* struct: from location hash bucket */
#define GPROF_TOS 3 /* struct: destination/count structure */
#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */
__BEGIN_DECLS
/* Set up data structures and start profiling. */
void monstartup __P ((u_long lowpc, u_long highpc));
/* Clean up profiling and write out gmon.out. */
void _mcleanup __P ((void));
__END_DECLS
#endif /* !_SYS_GMON_H_ */
+1
View File
@@ -46,5 +46,6 @@ Cambridge, MA 02139, USA. */
#define _GNU_OBSTACK_INTERFACE_VERSION 1 /* vs malloc/obstack.c */
#define _GNU_REGEX_INTERFACE_VERSION 1 /* vs posix/regex.c */
#define _GNU_GLOB_INTERFACE_VERSION 1 /* vs posix/glob.c */
#endif /* gnu-versions.h */
-1
View File
@@ -1 +0,0 @@
#include <posix/gnu/types.h>
+9 -8
View File
@@ -1,4 +1,4 @@
# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
# Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -25,18 +25,19 @@ include ../Makeconfig
headers = hurd.h $(interface-headers) \
$(addprefix hurd/,fd.h id.h port.h signal.h userlink.h \
resource.h threadvar.h lookup.h)
$(addprefix hurd/,fd.h id.h port.h signal.h sigpreempt.h \
userlink.h resource.h threadvar.h lookup.h)
distribute := hurdstartup.h hurdfault.h intr-rpc.defs STATUS
# The RPC interfaces go in a separate library.
interface-library := libhurduser
user-interfaces := $(addprefix hurd/,\
auth process startup \
auth startup \
process process_request \
msg msg_reply msg_request \
exec crash interrupt \
fs fsys io term socket ifsock)
exec exec_startup crash interrupt \
fs fsys io term tioctl socket ifsock)
server-interfaces := hurd/msg
routines = hurdstartup hurdinit \
@@ -50,10 +51,10 @@ routines = hurdstartup hurdinit \
fopenport \
vpprintf \
ports-get ports-set hurdports hurdmsg \
$(sig) $(dtable) hurdinline port-cleanup
$(sig) $(dtable) hurdinline port-cleanup report-wait
sig = hurdsig hurdfault faultexc siginfo hurd-raise preempt-sig \
trampoline longjmp-ts catch-exc exc2signal hurdkill sigunwind \
thread-self thread-cancel intr-msg
thread-self thread-cancel intr-msg catch-signal
dtable = dtable port2fd new-fd alloc-fd intern-fd \
getdport openport \
fd-close fd-read fd-write hurdioctl ctty-input ctty-output
+166
View File
@@ -0,0 +1,166 @@
/* Convenience function to catch expected signals during an operation.
Copyright (C) 1996 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., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <hurd/signal.h>
#include <hurd/sigpreempt.h>
#include <string.h>
#include <assert.h>
error_t
hurd_catch_signal (sigset_t sigset,
unsigned long int first, unsigned long int last,
error_t (*operate) (struct hurd_signal_preempter *),
sighandler_t handler)
{
jmp_buf buf;
void throw (int signo, long int sigcode, struct sigcontext *scp)
{ longjmp (buf, scp->sc_error ?: EGRATUITOUS); }
struct hurd_signal_preempter preempter =
{
sigset, first, last,
NULL, handler == SIG_ERR ? (sighandler_t) &throw : handler,
};
struct hurd_sigstate *const ss = _hurd_self_sigstate ();
error_t error;
if (handler == SIG_ERR)
/* Not our handler; don't bother saving state. */
error = 0;
else
/* This returns again with nonzero value when we preempt a signal. */
error = setjmp (buf);
if (error == 0)
{
/* Install a signal preempter for the thread. */
__spin_lock (&ss->lock);
preempter.next = ss->preempters;
ss->preempters = &preempter;
__spin_unlock (&ss->lock);
/* Try the operation that might crash. */
(*operate) (&preempter);
}
/* Either FUNCTION completed happily and ERROR is still zero, or it hit
an expected signal and `throw' made setjmp return the signal error
code in ERROR. Now we can remove the preempter and return. */
__spin_lock (&ss->lock);
assert (ss->preempters == &preempter);
ss->preempters = preempter.next;
__spin_unlock (&ss->lock);
return error;
}
error_t
hurd_safe_memset (void *dest, int byte, size_t nbytes)
{
error_t operate (struct hurd_signal_preempter *preempter)
{
memset (dest, byte, nbytes);
return 0;
}
return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV),
(vm_address_t) dest, (vm_address_t) dest + nbytes,
&operate, SIG_ERR);
}
error_t
hurd_safe_copyout (void *dest, const void *src, size_t nbytes)
{
error_t operate (struct hurd_signal_preempter *preempter)
{
memcpy (dest, src, nbytes);
return 0;
}
return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV),
(vm_address_t) dest, (vm_address_t) dest + nbytes,
&operate, SIG_ERR);
}
error_t
hurd_safe_copyin (void *dest, const void *src, size_t nbytes)
{
error_t operate (struct hurd_signal_preempter *preempter)
{
memcpy (dest, src, nbytes);
return 0;
}
return hurd_catch_signal (sigmask (SIGBUS) | sigmask (SIGSEGV),
(vm_address_t) src, (vm_address_t) src + nbytes,
&operate, SIG_ERR);
}
error_t
hurd_safe_memmove (void *dest, const void *src, size_t nbytes)
{
jmp_buf buf;
void throw (int signo, long int sigcode, struct sigcontext *scp)
{ longjmp (buf, scp->sc_error ?: EGRATUITOUS); }
struct hurd_signal_preempter src_preempter =
{
sigmask (SIGBUS) | sigmask (SIGSEGV),
(vm_address_t) src, (vm_address_t) src + nbytes,
NULL, (sighandler_t) &throw,
};
struct hurd_signal_preempter dest_preempter =
{
sigmask (SIGBUS) | sigmask (SIGSEGV),
(vm_address_t) dest, (vm_address_t) dest + nbytes,
NULL, (sighandler_t) &throw,
&src_preempter
};
struct hurd_sigstate *const ss = _hurd_self_sigstate ();
error_t error;
/* This returns again with nonzero value when we preempt a signal. */
error = setjmp (buf);
if (error == 0)
{
/* Install a signal preempter for the thread. */
__spin_lock (&ss->lock);
src_preempter.next = ss->preempters;
ss->preempters = &dest_preempter;
__spin_unlock (&ss->lock);
/* Do the copy; it might fault. */
memmove (dest, src, nbytes);
}
/* Either memmove completed happily and ERROR is still zero, or it hit
an expected signal and `throw' made setjmp return the signal error
code in ERROR. Now we can remove the preempter and return. */
__spin_lock (&ss->lock);
assert (ss->preempters == &dest_preempter);
ss->preempters = src_preempter.next;
__spin_unlock (&ss->lock);
return error;
}
+6 -4
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -29,9 +29,11 @@ DEFUN(fchroot, (fd), int fd)
error_t err;
file_t dir;
err = HURD_DPORT_USE (fd, (dir = __file_name_lookup_under (port, "",
O_EXEC, 0),
errno));
err = HURD_DPORT_USE (fd,
({
dir = __file_name_lookup_under (port, "", O_EXEC, 0);
dir == MACH_PORT_NULL ? errno : 0;
}));
if (! err)
_hurd_port_set (&_hurd_ports[INIT_PORT_CRDIR], dir);
+2 -2
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1993, 1994, 1995, 1996 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
@@ -146,7 +146,7 @@ extern error_t _hurd_ports_set (unsigned int which, mach_port_t newport);
extern process_t getproc (void);
extern file_t getcwdir (void), getcrdir (void);
extern auth_t getauth (void);
extern mach_port_t getcttyid ();
extern mach_port_t getcttyid (void);
extern int setproc (process_t);
extern int setcwdir (file_t), setcrdir (file_t);
extern int setcttyid (mach_port_t);
+6 -3
View File
@@ -1,5 +1,5 @@
/* User-registered handlers for specific `ioctl' requests.
Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1993, 1994, 1995, 1996 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
@@ -22,6 +22,7 @@ Cambridge, MA 02139, USA. */
#define __need___va_list
#include <stdarg.h>
#include <ioctls.h>
/* Type of handler function, called like ioctl to do its entire job. */
@@ -30,7 +31,8 @@ typedef int (*ioctl_handler_t) (int fd, int request, void *arg);
/* Structure that records an ioctl handler. */
struct ioctl_handler
{
int first_request, last_request; /* Range of handled request values. */
/* Range of handled _IOC_NOTYPE (REQUEST) values. */
int first_request, last_request;
/* Handler function, called like ioctl to do its entire job. */
ioctl_handler_t handler;
@@ -54,7 +56,8 @@ extern int hurd_register_ioctl_handler (int first_request, int last_request,
#define _HURD_HANDLE_IOCTLS(handler, first, last) \
static const struct ioctl_handler handler##_ioctl_handler \
__attribute__ ((__unused__)) = \
{ (first), (last), (int (*) (int, int, void *)) (handler), NULL }; \
{ _IOC_NOTYPE (first), _IOC_NOTYPE (last), \
(int (*) (int, int, void *)) (handler), NULL }; \
text_set_element (_hurd_ioctl_handler_lists, ##handler##_ioctl_handler)
/* Define a library-internal handler for a single ioctl command. */
+6 -4
View File
@@ -1,5 +1,5 @@
/* Resource limits for the Hurd.
Copyright (C) 1994 Free Software Foundation, Inc.
Copyright (C) 1994, 1995 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
@@ -33,11 +33,13 @@ extern struct mutex _hurd_rlimit_lock; /* Locks _hurd_rlimits. */
/* Helper function for getpriority and setpriority. Maps FN over all the
processes specified by WHICH and WHO. PI is non-null if a
proc_getprocinfo was already done; FN may use *PI arbitrarily, it is
reset on the next call. Returns FN's result the first time it returns
nonzero. If FN never returns nonzero, this returns zero. */
reset on the next call; PI_FLAGS is passed to proc_getprocinfo. Returns
FN's result the first time it returns nonzero. If FN never returns
nonzero, this returns zero. */
extern error_t _hurd_priority_which_map (enum __priority_which which, int who,
error_t (*fn) (pid_t pid,
struct procinfo *pi));
struct procinfo *pi),
int pi_flags);
/* Convert between Mach priority values and the priority
values used by getpriority, setpriority, and nice. */
+9 -40
View File
@@ -1,5 +1,5 @@
/* Implementing POSIX.1 signals under the Hurd.
Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1993, 1994, 1995, 1996 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
@@ -40,6 +40,7 @@ Cambridge, MA 02139, USA. */
#include <cthreads.h> /* For `struct mutex'. */
#include <spin-lock.h>
#include <hurd/threadvar.h> /* We cache sigstate in a threadvar. */
struct hurd_signal_preempter; /* <hurd/sigpreempt.h> */
/* Per-thread signal state. */
@@ -57,6 +58,13 @@ struct hurd_sigstate
sigset_t pending; /* Pending signals, possibly blocked. */
struct sigaction actions[NSIG];
struct sigaltstack sigaltstack;
/* Chain of thread-local signal preempters; see <hurd/sigpreempt.h>.
Each element of this chain is in local stack storage, and the chain
parallels the stack: the head of this chain is in the innermost
stack frame, and each next element in an outermore frame. */
struct hurd_signal_preempter *preempters;
struct
{
/* For each signal that may be pending, the
@@ -330,45 +338,6 @@ extern mach_msg_timeout_t _hurd_interrupted_rpc_timeout;
__err == MIG_SERVER_DIED); \
__err; \
})
/* Some other parts of the library need to preempt signals, to detect
errors that should not result in a POSIX signal. For example, when
some mapped region of memory is used, an extraneous SIGSEGV might be
generated when the mapping server returns an error for a page fault. */
struct hurd_signal_preempt
{
/* Function to examine a thread receiving a given signal. The handler
is called even for blocked signals. This function is run in the
signal thread, with THREAD's sigstate locked; it should be as simple
and robust as possible. THREAD is the thread which is about to
receive the signal. SIGNO and SIGCODE would be passed to the normal
handler.
If the return value is SIG_DFL, normal signal processing continues.
If it is SIG_IGN, the signal is ignored.
Any other value is used in place of the normal handler. */
sighandler_t (*handler) (thread_t thread,
int signo, long int sigcode, int sigerror);
long int first, last; /* Range of sigcodes this handler wants. */
struct hurd_signal_preempt *next; /* Next handler on the chain. */
};
extern struct hurd_signal_preempt *_hurd_signal_preempt[NSIG];
extern struct mutex _hurd_signal_preempt_lock;
/* Install a signal preempter for the given signal and range.
The caller is responsible for the storage for PREEMPTER. */
extern int hurd_preempt_signals (struct hurd_signal_preempt *preempter,
int signo, int first_code, int last_code,
sighandler_t (*handler) (thread_t,
int, long int, int));
/* Remove the signal preempter previously installed by calling
`hurd_preempt_signals' with PREEMPTER and SIGNO. */
extern int hurd_unpreempt_signals (struct hurd_signal_preempt *preempter,
int signo);
#endif /* hurd/signal.h */
+102
View File
@@ -0,0 +1,102 @@
/* Preemption of Hurd signals before POSIX.1 semantics take over.
Copyright (C) 1996 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., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifndef _HURD_SIGPREEMPT_H
#define _HURD_SIGPREEMPT_H 1
#include <errno.h>
#include <signal.h> /* For sigset_t, sighandler_t, SIG_ERR. */
struct hurd_sigstate; /* <hurd/signal.h> */
struct hurd_signal_preempter
{
/* These members select which signals this structure will apply to.
The rest of the structure is only consulted if these match. */
sigset_t signals; /* Signals preempted. */
unsigned long int first, last; /* Range of sigcode values preempted. */
/* This function will be called (with SS->lock held) to decide what to
do with the signal described. It may modify the codes of the signal
passed. If the return value is SIG_ERR, the next matching preempter
is tried, or the normal handling is done for the signal (which may
have been changed by the preempter function). Otherwise, the signal
is processed as if the return value were its handler setting. */
sighandler_t (*preempter) (struct hurd_signal_preempter *preempter,
struct hurd_sigstate *ss,
int *signo, long int *sigcode, int *sigerror);
/* If PREEMPTER is null, act as if it returned HANDLER. */
sighandler_t handler;
struct hurd_signal_preempter *next; /* List structure. */
};
#define HURD_PREEMPT_SIGNAL_P(preempter, signo, sigcode) \
(((preempter)->signals & sigmask (signo)) && \
(sigcode) >= (preempter)->first && (sigcode) <= (preempter)->last)
/* Signal preempters applying to all threads; locked by _hurd_siglock. */
extern struct hurd_signal_preempter *_hurdsig_preempters;
extern sigset_t _hurdsig_preempted_set;
/* The caller must initialize all members of *PREEMPTER except `next'.
The preempter is registered on the global list. */
void hurd_preempt_signals (struct hurd_signal_preempter *preempter);
/* Remove a preempter registered with hurd_preempt_signals. */
void hurd_unpreempt_signals (struct hurd_signal_preempter *preempter);
/* Call *OPERATE and return its value. If a signal in SIGSET with a sigcode
in the range [FIRST,LAST] arrives during the call, catch it. If HANDLER
is a function, it handles the signal in the normal way (i.e. it should
longjmp unless it can restart the insn on return). If it is SIG_ERR,
hurd_catch_signal returns the sc_error value from the signal (or
EGRATUITOUS if that is zero).
The preempter structure is passed to *OPERATE, which may modify its
sigcode range or functions at any time during which it is guaranteed no
signal in SIGSET will arrive. */
error_t hurd_catch_signal (sigset_t sigset,
unsigned long int first, unsigned long int last,
error_t (*operate) (struct hurd_signal_preempter *),
sighandler_t handler);
/* Convenience functions using `hurd_catch_signal'. */
/* Like `memset', but catch faults in DEST. */
error_t hurd_safe_memset (void *dest, int byte, size_t nbytes);
/* Like `memcpy', but catch faults in SRC. */
error_t hurd_safe_copyin (void *dest, const void *src, size_t nbytes);
/* Like `memcpy', but catch faults in DEST. */
error_t hurd_safe_copyout (void *dest, const void *src, size_t nbytes);
/* Like `memmove', but catch faults in SRC or DEST.
If only one region is expected to fault, it is more efficient
to use `hurd_safe_copyin' or `hurd_safe_copyout' as appropriate. */
error_t hurd_safe_memmove (void *dest, const void *src, size_t nbytes);
#endif /* hurd/sigpreempt.h */
+3 -3
View File
@@ -30,7 +30,7 @@ Cambridge, MA 02139, USA. */
If TASK == mach_task_self (), some ports are dealloc'd by the exec server.
ARGV and ENVP are terminated by NULL pointers. */
error_t
_hurd_exec (task_t task, file_t file,
_hurd_exec (task_t task, file_t file,
char *const argv[], char *const envp[])
{
error_t err;
@@ -129,7 +129,7 @@ _hurd_exec (task_t task, file_t file,
in the exec, or the signal will never be delivered. Setting the
critical section flag avoids anything we call trying to acquire the
sigstate lock. */
ss->critical_section = 1;
__spin_unlock (&ss->lock);
@@ -224,7 +224,7 @@ _hurd_exec (task_t task, file_t file,
ports, MACH_MSG_TYPE_COPY_SEND, _hurd_nports,
ints, INIT_INT_MAX,
please_dealloc, pdp - please_dealloc,
NULL, 0);
&_hurd_msgport, task == __mach_task_self () ? 1 : 0);
}
/* Release references to the standard ports. */
+55 -39
View File
@@ -1,5 +1,5 @@
/* Handle faults in the signal thread.
Copyright (C) 1994 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1996 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
@@ -26,15 +26,13 @@ Cambridge, MA 02139, USA. */
#include <stdio.h>
#include "thread_state.h"
#include "faultexc.h" /* mig-generated header for our exc server. */
#include <assert.h>
jmp_buf _hurdsig_fault_env;
struct hurd_signal_preempter _hurdsig_fault_preempter;
static mach_port_t forward_sigexc;
int _hurdsig_fault_expect_signo;
long int _hurdsig_fault_sigcode;
int _hurdsig_fault_sigerror;
kern_return_t
_hurdsig_fault_catch_exception_raise (mach_port_t port,
thread_t thread,
@@ -44,6 +42,8 @@ _hurdsig_fault_catch_exception_raise (mach_port_t port,
int subcode)
{
int signo;
long int sigcode;
int sigerror;
if (port != forward_sigexc ||
thread != _hurd_msgport_thread || task != __mach_task_self ())
@@ -51,10 +51,11 @@ _hurdsig_fault_catch_exception_raise (mach_port_t port,
/* Call the machine-dependent function to translate the Mach exception
codes into a signal number and subcode. */
_hurd_exception2signal (exception, code, subcode, &signo,
&_hurdsig_fault_sigcode, &_hurdsig_fault_sigerror);
_hurd_exception2signal (exception, code, subcode,
&signo, &sigcode, &sigerror);
return signo == _hurdsig_fault_expect_signo ? 0 : EGREGIOUS;
return HURD_PREEMPT_SIGNAL_P (&_hurdsig_fault_preempter, signo, sigcode)
? 0 : EGREGIOUS;
}
static void
@@ -84,19 +85,17 @@ faulted (void)
/* Run the exc demuxer which should call the server function above.
That function returns 0 if the exception was expected. */
switch (_hurdsig_fault_exc_server (&request.head, &reply.head))
{
case KERN_SUCCESS:
if (reply.head.msgh_remote_port != MACH_PORT_NULL)
__mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size,
0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
break;
default:
__mach_msg_destroy (&request.head);
case MIG_NO_REPLY:
}
_hurdsig_fault_exc_server (&request.head, &reply.head);
if (reply.head.msgh_remote_port != MACH_PORT_NULL)
__mach_msg (&reply.head, MACH_SEND_MSG, reply.head.msgh_size,
0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
if (reply.result == MIG_BAD_ID)
__mach_msg_destroy (&request.head);
_hurdsig_fault_expect_signo = 0;
if (reply.result)
__libc_fatal ("BUG: unexpected fault in signal thread\n");
_hurdsig_fault_preempter.signals = 0;
longjmp (_hurdsig_fault_env, 1);
}
@@ -114,30 +113,47 @@ _hurdsig_fault_init (void)
struct machine_thread_state state;
mach_port_t sigexc;
if (err = __mach_port_allocate (__mach_task_self (),
MACH_PORT_RIGHT_RECEIVE, &sigexc))
__libc_fatal ("hurd: Can't create receive right for signal thread exc\n");
if (err = __mach_port_allocate (__mach_task_self (),
MACH_PORT_RIGHT_RECEIVE, &forward_sigexc))
__libc_fatal ("hurd: Can't create receive right for signal thread exc\n");
/* Allocate a port to receive signal thread exceptions.
We will move this receive right to the proc server. */
err = __mach_port_allocate (__mach_task_self (),
MACH_PORT_RIGHT_RECEIVE, &sigexc);
assert_perror (err);
err = __mach_port_allocate (__mach_task_self (),
MACH_PORT_RIGHT_RECEIVE, &forward_sigexc);
assert_perror (err);
/* Allocate a port to receive the exception msgs forwarded
from the proc server. */
err = __mach_port_insert_right (__mach_task_self (), sigexc,
sigexc, MACH_MSG_TYPE_MAKE_SEND);
assert_perror (err);
/* Set the queue limit for this port to just one. The proc server will
notice if we ever get a second exception while one remains queued and
unreceived, and decide we are hopelessly buggy. */
err = __mach_port_set_qlimit (__mach_task_self (), forward_sigexc, 1);
assert_perror (err);
/* This state will be restored when we fault.
It runs the function above. */
memset (&state, 0, sizeof state);
MACHINE_THREAD_STATE_SET_PC (&state, faulted);
MACHINE_THREAD_STATE_SET_SP (&state, faultstack, sizeof faultstack);
#if 0 /* Don't confuse gdb. */
__thread_set_special_port (_hurd_msgport_thread,
THREAD_EXCEPTION_PORT, sigexc);
#endif
err = __USEPORT
(PROC,
__proc_handle_exceptions (port,
sigexc,
forward_sigexc, MACH_MSG_TYPE_MAKE_SEND,
MACHINE_THREAD_STATE_FLAVOR,
(natural_t *) &state,
MACHINE_THREAD_STATE_COUNT));
assert_perror (err);
if (err = __USEPORT
(PROC,
__proc_handle_exceptions (port,
sigexc,
forward_sigexc, MACH_MSG_TYPE_MAKE_SEND,
MACHINE_THREAD_STATE_FLAVOR,
(natural_t *) &state,
MACHINE_THREAD_STATE_COUNT)))
__libc_fatal ("hurd: proc won't handle signal thread exceptions\n");
/* Direct signal thread exceptions to the proc server. */
err = __thread_set_special_port (_hurd_msgport_thread,
THREAD_EXCEPTION_PORT, sigexc);
__mach_port_deallocate (__mach_task_self (), sigexc);
assert_perror (err);
}
+13 -11
View File
@@ -1,5 +1,5 @@
/* Declarations for handling faults in the signal thread.
Copyright (C) 1994 Free Software Foundation, Inc.
Copyright (C) 1994, 1996 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
@@ -20,6 +20,7 @@ Cambridge, MA 02139, USA. */
#ifndef _HURD_FAULT_H
#define _HURD_FAULT_H
#include <hurd/sigpreempt.h>
#include <setjmp.h>
/* Call this before code that might fault in the signal thread; SIGNO is
@@ -27,23 +28,24 @@ Cambridge, MA 02139, USA. */
returns zero the first time, and returns again nonzero if the signal
does arrive. */
#define _hurdsig_catch_fault(signo) \
(_hurdsig_fault_expect_signo = (signo), setjmp (_hurdsig_fault_env))
#define _hurdsig_catch_fault(sigset, firstcode, lastcode) \
(_hurdsig_fault_preempter.signals = (sigset), \
_hurdsig_fault_preempter.first = (long int) (firstcode), \
_hurdsig_fault_preempter.last = (long int) (lastcode), \
setjmp (_hurdsig_fault_env))
/* Call this at the end of a section protected by _hurdsig_catch_fault. */
#define _hurdsig_end_catch_fault() \
(_hurdsig_fault_expect_signo = 0)
(_hurdsig_fault_preempter.signals = 0)
extern jmp_buf _hurdsig_fault_env;
extern int _hurdsig_fault_expect_signo;
/* If _hurdsig_catch_fault returns nonzero, these variables
contain information about the signal that arrived. */
extern struct hurd_signal_preempter _hurdsig_fault_preempter;
#define _hurdsig_catch_memory_fault(object) \
_hurdsig_catch_fault (sigmask (SIGSEGV) | sigmask (SIGBUS), \
(object), (object) + 1)
extern long int _hurdsig_fault_sigcode;
extern int _hurdsig_fault_sigerror;
#endif /* hurd/fault.h */
#endif /* hurdfault.h */
+26 -2
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1992, 1993, 1994, 1995, 1996 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
@@ -151,7 +151,7 @@ _hurd_proc_init (char **argv)
/* This process is "traced", meaning it should stop on signals or exec.
We are all set up now to handle signals. Stop ourselves, to inform
our parent (presumably a debugger) that the exec has completed. */
_hurd_raise_signal (NULL, SIGTRAP, 0, 0);
__msg_sig_post (_hurd_msgport, SIGTRAP, __mach_task_self ());
}
/* Called when we get a message telling us to change our proc server port. */
@@ -197,3 +197,27 @@ _hurd_setproc (process_t procserver)
return 0;
}
#ifndef PIC
/* Map the page at address zero with no access allowed, so
dereferencing NULL will fault and no "anywhere" allocations
(e.g. the out of line memory containing the argument strings)
can be assigned address zero, which C says is not a valid pointer.
When dynamically linked, this will be done by the dynamic linker
before we run. */
static void map0 (void) __attribute__ ((unused));
text_set_element (_hurd_preinit_hook, map0);
static void
map0 (void)
{
vm_address_t addr = 0;
__vm_map (__mach_task_self (),
&addr, __vm_page_size, 0, 0, MACH_PORT_NULL, 0, 1,
VM_PROT_NONE, VM_PROT_NONE, VM_INHERIT_COPY);
}
#endif
+16 -6
View File
@@ -1,5 +1,5 @@
/* ioctl commands which must be done in the C library.
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
Copyright (C) 1994, 1995, 1996 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
@@ -36,6 +36,10 @@ _hurd_lookup_ioctl_handler (int request)
void *const *ptr;
const struct ioctl_handler *h;
/* Mask off the type bits, so that we see requests in a single group as a
contiguous block of values. */
request = _IOC_NOTYPE (request);
for (ptr = symbol_set_first_element (_hurd_ioctl_handler_lists);
!symbol_set_end_p (_hurd_ioctl_handler_lists, ptr);
++ptr)
@@ -62,7 +66,7 @@ fioctl (int fd,
switch (request)
{
default:
err = EGRATUITOUS;
err = ENOTTY;
break;
case FIONREAD:
@@ -97,7 +101,7 @@ fioctl (int fd,
break;
}
return err ? __hurd_fail (err) : 0;
return err ? __hurd_dfail (fd, err) : 0;
}
_HURD_HANDLE_IOCTLS (fioctl, FIOGETOWN, FIONREAD);
@@ -112,7 +116,7 @@ fioclex (int fd,
switch (request)
{
default:
return __hurd_fail (EGRATUITOUS);
return __hurd_fail (ENOTTY);
case FIOCLEX:
flag = FD_CLOEXEC;
break;
@@ -126,12 +130,13 @@ fioclex (int fd,
_HURD_HANDLE_IOCTLS (fioclex, FIOCLEX, FIONCLEX);
#include <hurd/term.h>
#include <hurd/tioctl.h>
static void
rectty_dtable (mach_port_t cttyid)
{
int i;
HURD_CRITICAL_BEGIN;
__mutex_lock (&_hurd_dtable_lock);
@@ -222,6 +227,11 @@ tiocsctty (int fd,
else if (err)
return __hurd_fail (err);
/* Change the terminal's pgrp to ours. */
err = HURD_DPORT_USE (fd, __tioctl_tiocspgrp (port, _hurd_pgrp));
if (err)
return __hurd_fail (err);
/* Make it our own. */
_hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], cttyid);
@@ -256,7 +266,7 @@ tiocnotty (int fd,
_hurd_port_set (&_hurd_ports[INIT_PORT_CTTYID], MACH_PORT_NULL);
/* Reset all the ctty ports in all the descriptors. */
__USEPORT (CTTYID, (rectty_dtable (MACH_PORT_NULL), 0));
return 0;
+16 -7
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 94, 95, 96 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
@@ -58,16 +58,25 @@ _hurd_sig_post (pid_t pid, int sig, mach_port_t arg_refport)
err = __proc_getpgrppids (proc, - pid, &pids, &npids);
if (!err)
{
int self = 0;
for (i = 0; i < npids; ++i)
{
kill_pid (pids[i]);
if (err == ESRCH)
/* The process died already. Ignore it. */
err = 0;
}
if (pids[i] == _hurd_pid)
/* We must do ourselves last so we are not suspended
and fail to suspend the other processes in the pgrp. */
self = 1;
else
{
kill_pid (pids[i]);
if (err == ESRCH)
/* The process died already. Ignore it. */
err = 0;
}
if (pids != pidsbuf)
__vm_deallocate (__mach_task_self (),
(vm_address_t) pids, npids * sizeof (pids[0]));
if (self)
kill_pid (_hurd_pid);
}
}
else

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