about summary refs log tree commit diff
path: root/db2/os
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1999-06-13 13:36:34 +0000
committerUlrich Drepper <drepper@redhat.com>1999-06-13 13:36:34 +0000
commitec239360d13518a13f572b635d036c7d10028010 (patch)
treebdb5111363f45d2107849c2456b575d72779174c /db2/os
parentfc3703521650a9b6db910a50c4fc0f410496e134 (diff)
downloadglibc-ec239360d13518a13f572b635d036c7d10028010.tar.gz
glibc-ec239360d13518a13f572b635d036c7d10028010.tar.xz
glibc-ec239360d13518a13f572b635d036c7d10028010.zip
Update.
	* db2/Makefile (distribute): Remove files which do not exist
	anymore.
Diffstat (limited to 'db2/os')
-rw-r--r--db2/os/os_abs.c8
-rw-r--r--db2/os/os_alloc.c202
-rw-r--r--db2/os/os_config.c66
-rw-r--r--db2/os/os_dir.c25
-rw-r--r--db2/os/os_fid.c8
-rw-r--r--db2/os/os_fsync.c42
-rw-r--r--db2/os/os_map.c72
-rw-r--r--db2/os/os_oflags.c2
-rw-r--r--db2/os/os_open.c75
-rw-r--r--db2/os/os_rw.c82
-rw-r--r--db2/os/os_seek.c22
-rw-r--r--db2/os/os_sleep.c6
-rw-r--r--db2/os/os_spin.c92
-rw-r--r--db2/os/os_stat.c11
-rw-r--r--db2/os/os_tmpdir.c113
-rw-r--r--db2/os/os_unlink.c15
16 files changed, 590 insertions, 251 deletions
diff --git a/db2/os/os_abs.c b/db2/os/os_abs.c
index d9f4970467..547a6804b4 100644
--- a/db2/os/os_abs.c
+++ b/db2/os/os_abs.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_abs.c	10.8 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)os_abs.c	10.9 (Sleepycat) 7/21/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -18,13 +18,13 @@ static const char sccsid[] = "@(#)os_abs.c	10.8 (Sleepycat) 4/10/98";
 #include "db_int.h"
 
 /*
- * __db_abspath --
+ * __os_abspath --
  *	Return if a path is an absolute path.
  *
- * PUBLIC: int __db_abspath __P((const char *));
+ * PUBLIC: int __os_abspath __P((const char *));
  */
 int
-__db_abspath(path)
+__os_abspath(path)
 	const char *path;
 {
 	return (path[0] == '/');
diff --git a/db2/os/os_alloc.c b/db2/os/os_alloc.c
index 35784476c0..0090eb14a7 100644
--- a/db2/os/os_alloc.c
+++ b/db2/os/os_alloc.c
@@ -8,40 +8,22 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_alloc.c	10.6 (Sleepycat) 5/2/98";
+static const char sccsid[] = "@(#)os_alloc.c	10.10 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
 #include <sys/types.h>
 
+#include <errno.h>
 #include <string.h>
+#include <stdlib.h>
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
- * __db_strdup --
- *	The strdup(3) function for DB.
- *
- * PUBLIC: char *__db_strdup __P((const char *));
- */
-char *
-__db_strdup(str)
-	const char *str;
-{
-	size_t len;
-	char *copy;
-
-	len = strlen(str) + 1;
-	if ((copy = __db_malloc(len)) == NULL)
-		return (NULL);
-
-	memcpy(copy, str, len);
-	return (copy);
-}
-
-/*
- * XXX
+ * !!!
  * Correct for systems that return NULL when you allocate 0 bytes of memory.
  * There are several places in DB where we allocate the number of bytes held
  * by the key/data item, and it can be 0.  Correct here so that malloc never
@@ -49,59 +31,189 @@ __db_strdup(str)
  * could make these calls macros on non-Alpha architectures (that's where we
  * saw the problem), but it's probably not worth the autoconf complexity.
  *
+ * !!!
+ * Correct for systems that don't set errno when malloc and friends fail.
+ *
  *	Out of memory.
  *	We wish to hold the whole sky,
  *	But we never will.
  */
+
+/*
+ * __os_strdup --
+ *	The strdup(3) function for DB.
+ *
+ * PUBLIC: int __os_strdup __P((const char *, void *));
+ */
+int
+__os_strdup(str, storep)
+	const char *str;
+	void *storep;
+{
+	size_t size;
+	int ret;
+	void *p;
+
+	*(void **)storep = NULL;
+
+	size = strlen(str) + 1;
+	if ((ret = __os_malloc(size, NULL, &p)) != 0)
+		return (ret);
+
+	memcpy(p, str, size);
+
+	*(void **)storep = p;
+	return (0);
+}
+
 /*
- * __db_calloc --
+ * __os_calloc --
  *	The calloc(3) function for DB.
  *
- * PUBLIC: void *__db_calloc __P((size_t, size_t));
+ * PUBLIC: int __os_calloc __P((size_t, size_t, void *));
  */
-void *
-__db_calloc(num, size)
+int
+__os_calloc(num, size, storep)
 	size_t num, size;
+	void *storep;
 {
 	void *p;
+	int ret;
 
 	size *= num;
-	if ((p = __db_jump.j_malloc(size == 0 ? 1 : size)) != NULL)
-		memset(p, 0, size);
-	return (p);
+	if ((ret = __os_malloc(size, NULL, &p)) != 0)
+		return (ret);
+
+	memset(p, 0, size);
+	*(void **)storep = p;
+
+	return (0);
 }
 
 /*
- * __db_malloc --
+ * __os_malloc --
  *	The malloc(3) function for DB.
  *
- * PUBLIC: void *__db_malloc __P((size_t));
+ * PUBLIC: int __os_malloc __P((size_t, void *(*)(size_t), void *));
  */
-void *
-__db_malloc(size)
+int
+__os_malloc(size, db_malloc, storep)
 	size_t size;
+	void *(*db_malloc) __P((size_t)), *storep;
 {
-#ifdef DIAGNOSTIC
 	void *p;
 
-	p = __db_jump.j_malloc(size == 0 ? 1 : size);
-	memset(p, 0xff, size == 0 ? 1 : size);
-	return (p);
-#else
-	return (__db_jump.j_malloc(size == 0 ? 1 : size));
+	*(void **)storep = NULL;
+
+	/* Never allocate 0 bytes -- some C libraries don't like it. */
+	if (size == 0)
+		++size;
+
+	/* Some C libraries don't correctly set errno when malloc(3) fails. */
+	errno = 0;
+	if (db_malloc != NULL)
+		p = db_malloc(size);
+	else if (__db_jump.j_malloc != NULL)
+		p = __db_jump.j_malloc(size);
+	else
+		p = malloc(size);
+	if (p == NULL) {
+		if (errno == 0)
+			errno = ENOMEM;
+		return (errno);
+	}
+
+#ifdef DIAGNOSTIC
+	memset(p, 0xdb, size);
 #endif
+	*(void **)storep = p;
+
+	return (0);
 }
 
 /*
- * __db_realloc --
+ * __os_realloc --
  *	The realloc(3) function for DB.
  *
- * PUBLIC: void *__db_realloc __P((void *, size_t));
+ * PUBLIC: int __os_realloc __P((void *, size_t));
+ */
+int
+__os_realloc(storep, size)
+	void *storep;
+	size_t size;
+{
+	void *p, *ptr;
+
+	ptr = *(void **)storep;
+
+	/* If we haven't yet allocated anything yet, simply call malloc. */
+	if (ptr == NULL)
+		return (__os_malloc(size, NULL, storep));
+
+	/* Never allocate 0 bytes -- some C libraries don't like it. */
+	if (size == 0)
+		++size;
+
+	/*
+	 * Some C libraries don't correctly set errno when realloc(3) fails.
+	 *
+	 * Don't overwrite the original pointer, there are places in DB we
+	 * try to continue after realloc fails.
+	 */
+	errno = 0;
+	if (__db_jump.j_realloc != NULL)
+		p = __db_jump.j_realloc(ptr, size);
+	else
+		p = realloc(ptr, size);
+	if (p == NULL) {
+		if (errno == 0)
+			errno = ENOMEM;
+		return (errno);
+	}
+
+	*(void **)storep = p;
+
+	return (0);
+}
+
+/*
+ * __os_free --
+ *	The free(3) function for DB.
+ *
+ * PUBLIC: void __os_free __P((void *, size_t));
  */
-void *
-__db_realloc(ptr, size)
+void
+__os_free(ptr, size)
 	void *ptr;
 	size_t size;
 {
-	return (__db_jump.j_realloc(ptr, size == 0 ? 1 : size));
+#ifdef DIAGNOSTIC
+	if (size != 0)
+		memset(ptr, 0xdb, size);
+#endif
+
+	if (__db_jump.j_free != NULL)
+		__db_jump.j_free(ptr);
+	else
+		free(ptr);
+}
+
+/*
+ * __os_freestr --
+ *	The free(3) function for DB, freeing a string.
+ *
+ * PUBLIC: void __os_freestr __P((void *));
+ */
+void
+__os_freestr(ptr)
+	void *ptr;
+{
+#ifdef DIAGNOSTIC
+	memset(ptr, 0xdb, strlen(ptr) + 1);
+#endif
+
+	if (__db_jump.j_free != NULL)
+		__db_jump.j_free(ptr);
+	else
+		free(ptr);
 }
diff --git a/db2/os/os_config.c b/db2/os/os_config.c
index 4150c843e4..71d379a387 100644
--- a/db2/os/os_config.c
+++ b/db2/os/os_config.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_config.c	10.26 (Sleepycat) 5/23/98";
+static const char sccsid[] = "@(#)os_config.c	10.30 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -18,72 +18,18 @@ static const char sccsid[] = "@(#)os_config.c	10.26 (Sleepycat) 5/23/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
-/*
- * XXX
- * We provide our own extern declarations so that we don't collide with
- * systems that get them wrong, e.g., SunOS.
- */
-#ifdef _WIN32
-#define fsync		_commit
-#define imported	__declspec(dllimport)
-#else
-#define imported
-#endif
-
-/*
- * XXX
- * HP/UX MPE doesn't have fsync, but you can build one using FCONTROL.
- */
-#ifdef __hp3000s900
-#define	fsync	__mpe_fsync
-#endif
-
-imported extern int	 close __P((int));
-imported extern void	 free __P((void *));
-imported extern int	 fsync __P((int));
-imported extern void    *malloc __P((size_t));
-imported extern int	 open __P((const char *, int, ...));
-imported extern ssize_t	 read __P((int, void *, size_t));
-imported extern void    *realloc __P((void *, size_t));
-imported extern int	 unlink __P((const char *));
-imported extern ssize_t	 write __P((int, const void *, size_t));
-
-/*
- * __db_jump --
- *	This list of interfaces that applications can replace.  In some
- *	cases, the user is permitted to replace the standard ANSI C or
- *	POSIX 1003.1 call, e.g., malloc or read.  In others, we provide
- *	a local interface to the functionality, e.g., __os_ioinfo.
- */
-struct __db_jumptab __db_jump = {
-	close,				/* DB_FUNC_CLOSE */
-	__os_dirfree,			/* DB_FUNC_DIRFREE */
-	__os_dirlist,			/* DB_FUNC_DIRLIST */
-	__os_exists,			/* DB_FUNC_EXISTS */
-	free,				/* DB_FUNC_FREE */
-	fsync,				/* DB_FUNC_FSYNC */
-	__os_ioinfo,			/* DB_FUNC_IOINFO */
-	malloc,				/* DB_FUNC_MALLOC */
-	NULL,				/* DB_FUNC_MAP */
-	open,				/* DB_FUNC_OPEN */
-	read,				/* DB_FUNC_READ */
-	realloc,			/* DB_FUNC_REALLOC */
-	NULL,				/* DB_FUNC_RUNLINK */
-	__os_seek,			/* DB_FUNC_SEEK */
-	__os_sleep,			/* DB_FUNC_SLEEP */
-	unlink,				/* DB_FUNC_UNLINK */
-	NULL,				/* DB_FUNC_UNMAP */
-	write,				/* DB_FUNC_WRITE */
-	NULL				/* DB_FUNC_YIELD */
-};
+struct __db_jumptab __db_jump;
 
 DB_GLOBALS __db_global_values = {
 	1,				/* DB_MUTEXLOCKS */
+	0,				/* DB_PAGEYIELD */
 	0,				/* DB_REGION_ANON, DB_REGION_NAME */
 	0,				/* DB_REGION_INIT */
 	0,				/* DB_TSL_SPINS */
-	0				/* DB_PAGEYIELD */
+        {NULL, &__db_global_values.db_envq.tqh_first},  /* Environemnt queue */
+	{NULL, &__db_global_values.db_nameq.tqh_first}	/* Name queue */
 };
 
 /*
diff --git a/db2/os/os_dir.c b/db2/os/os_dir.c
index 14a10ad23f..f2ee128c1e 100644
--- a/db2/os/os_dir.c
+++ b/db2/os/os_dir.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_dir.c	10.15 (Sleepycat) 4/26/98";
+static const char sccsid[] = "@(#)os_dir.c	10.19 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -35,6 +35,7 @@ static const char sccsid[] = "@(#)os_dir.c	10.15 (Sleepycat) 4/26/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
  * __os_dirlist --
@@ -50,22 +51,23 @@ __os_dirlist(dir, namesp, cntp)
 {
 	struct dirent *dp;
 	DIR *dirp;
-	int arraysz, cnt;
+	int arraysz, cnt, ret;
 	char **names;
 
+	if (__db_jump.j_dirlist != NULL)
+		return (__db_jump.j_dirlist(dir, namesp, cntp));
+
 	if ((dirp = opendir(dir)) == NULL)
 		return (errno);
 	names = NULL;
 	for (arraysz = cnt = 0; (dp = readdir(dirp)) != NULL; ++cnt) {
 		if (cnt >= arraysz) {
 			arraysz += 100;
-			names = (char **)(names == NULL ?
-			    __db_malloc(arraysz * sizeof(names[0])) :
-			    __db_realloc(names, arraysz * sizeof(names[0])));
-			if (names == NULL)
+			if ((ret = __os_realloc(&names,
+			    arraysz * sizeof(names[0]))) != 0)
 				goto nomem;
 		}
-		if ((names[cnt] = (char *)__db_strdup(dp->d_name)) == NULL)
+		if ((ret = __os_strdup(dp->d_name, &names[cnt])) != 0)
 			goto nomem;
 	}
 	(void)closedir(dirp);
@@ -76,7 +78,7 @@ __os_dirlist(dir, namesp, cntp)
 
 nomem:	if (names != NULL)
 		__os_dirfree(names, cnt);
-	return (ENOMEM);
+	return (ret);
 }
 
 /*
@@ -90,7 +92,10 @@ __os_dirfree(names, cnt)
 	char **names;
 	int cnt;
 {
+	if (__db_jump.j_dirfree != NULL)
+		__db_jump.j_dirfree(names, cnt);
+
 	while (cnt > 0)
-		__db_free(names[--cnt]);
-	__db_free(names);
+		__os_free(names[--cnt], 0);
+	__os_free(names, 0);
 }
diff --git a/db2/os/os_fid.c b/db2/os/os_fid.c
index cf48c01bd8..62da590611 100644
--- a/db2/os/os_fid.c
+++ b/db2/os/os_fid.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_fid.c	10.11 (Sleepycat) 4/26/98";
+static const char sccsid[] = "@(#)os_fid.c	10.12 (Sleepycat) 7/21/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -24,13 +24,13 @@ static const char sccsid[] = "@(#)os_fid.c	10.11 (Sleepycat) 4/26/98";
 #include "common_ext.h"
 
 /*
- * __db_fileid --
+ * __os_fileid --
  *	Return a unique identifier for a file.
  *
- * PUBLIC: int __db_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
+ * PUBLIC: int __os_fileid __P((DB_ENV *, const char *, int, u_int8_t *));
  */
 int
-__db_fileid(dbenv, fname, timestamp, fidp)
+__os_fileid(dbenv, fname, timestamp, fidp)
 	DB_ENV *dbenv;
 	const char *fname;
 	int timestamp;
diff --git a/db2/os/os_fsync.c b/db2/os/os_fsync.c
index e1f271a75c..61a504f84d 100644
--- a/db2/os/os_fsync.c
+++ b/db2/os/os_fsync.c
@@ -8,34 +8,21 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_fsync.c	10.5 (Sleepycat) 4/19/98";
+static const char sccsid[] = "@(#)os_fsync.c	10.7 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
 #include <sys/types.h>
 
 #include <errno.h>
+#include <fcntl.h>			/* XXX: Required by __hp3000s900 */
 #include <unistd.h>
 #endif
 
 #include "db_int.h"
-
-/*
- * __db_fsync --
- *	Flush a file descriptor.
- *
- * PUBLIC: int __db_fsync __P((int));
- */
-int
-__db_fsync(fd)
-	int fd;
-{
-	return (__os_fsync(fd) ? errno : 0);
-}
+#include "os_jump.h"
 
 #ifdef __hp3000s900
-#include <fcntl.h>
-
 int
 __mpe_fsync(fd)
 	int fd;
@@ -47,3 +34,26 @@ __mpe_fsync(fd)
 	return (0);
 }
 #endif
+
+#ifdef __hp3000s900
+#define	fsync(fd)	__mpe_fsync(fd);
+#endif
+#ifdef _WIN32
+#define	fsync(fd)	_commit(fd);
+#endif
+
+/*
+ * __os_fsync --
+ *	Flush a file descriptor.
+ *
+ * PUBLIC: int __os_fsync __P((int));
+ */
+int
+__os_fsync(fd)
+	int fd;
+{
+	int ret;
+
+	ret = __db_jump.j_fsync != NULL ?  __db_jump.j_fsync(fd) : fsync(fd);
+	return (ret == 0 ? 0 : errno);
+}
diff --git a/db2/os/os_map.c b/db2/os/os_map.c
index 5f0fd790e6..5664a2edec 100644
--- a/db2/os/os_map.c
+++ b/db2/os/os_map.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_map.c	10.19 (Sleepycat) 5/3/98";
+static const char sccsid[] = "@(#)os_map.c	10.24 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -27,13 +27,14 @@ static const char sccsid[] = "@(#)os_map.c	10.19 (Sleepycat) 5/3/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 #include "common_ext.h"
 
 #ifdef HAVE_MMAP
 static int __os_map __P((char *, int, size_t, int, int, int, void **));
 #endif
 #ifdef HAVE_SHMGET
-static int __os_shmget __P((char *, REGINFO *));
+static int __os_shmget __P((REGINFO *));
 #endif
 
 /*
@@ -165,7 +166,7 @@ __db_mapregion(path, infop)
 #ifdef HAVE_SHMGET
 		if (!called) {
 			called = 1;
-			ret = __os_shmget(path, infop);
+			ret = __os_shmget(infop);
 		}
 #endif
 #ifdef HAVE_MMAP
@@ -207,7 +208,7 @@ __db_mapregion(path, infop)
 #ifdef HAVE_SHMGET
 		if (!called) {
 			called = 1;
-			ret = __os_shmget(path, infop);
+			ret = __os_shmget(infop);
 		}
 #endif
 	}
@@ -271,10 +272,9 @@ __db_unlinkregion(name, infop)
 		called = 1;
 		ret = shmctl(infop->segid, IPC_RMID, NULL) ? errno : 0;
 	}
-#else
-	COMPQUIET(infop, NULL);
 #endif
 #ifdef HAVE_MMAP
+	COMPQUIET(infop, NULL);
 	if (!called) {
 		called = 1;
 		ret = 0;
@@ -388,6 +388,23 @@ __os_map(path, fd, len, is_region, is_anonymous, is_rdonly, addr)
 
 	prot = PROT_READ | (is_rdonly ? 0 : PROT_WRITE);
 
+/*
+ * XXX
+ * Work around a bug in the VMS V7.1 mmap() implementation.  To map a file
+ * into memory on VMS it needs to be opened in a certain way, originally.
+ * To get the file opened in that certain way, the VMS mmap() closes the
+ * file and re-opens it.  When it does this, it doesn't flush any caches
+ * out to disk before closing.  The problem this causes us is that when the
+ * memory cache doesn't get written out, the file isn't big enough to match
+ * the memory chunk and the mmap() call fails.  This call to fsync() fixes
+ * the problem.  DEC thinks this isn't a bug because of language in XPG5
+ * discussing user responsibility for on-disk and in-memory synchronization.
+ */
+#ifdef VMS
+	if (__os_fsync(fd) == -1)
+		return(errno);
+#endif
+
 	/* MAP_FAILED was not defined in early mmap implementations. */
 #ifndef MAP_FAILED
 #define	MAP_FAILED	-1
@@ -407,47 +424,12 @@ __os_map(path, fd, len, is_region, is_anonymous, is_rdonly, addr)
  *	Call the shmget(2) family of functions.
  */
 static int
-__os_shmget(path, infop)
+__os_shmget(infop)
 	REGINFO *infop;
-	char *path;
 {
-	key_t key;
-	int shmflg;
-
-	if (F_ISSET(infop, REGION_CREATED)) {
-		/*
-		 * The return key from ftok(3) is not guaranteed to be unique.
-		 * The nice thing about the shmget(2) interface is that it
-		 * allows you to name anonymous pieces of memory.  The evil
-		 * thing about it is that the name space is separate from the
-		 * filesystem.
-		 */
-#ifdef __hp3000s900
-		{char mpe_path[MAXPATHLEN];
-		/*
-		 * MPE ftok() is broken as of 5.5pp4.  If the file path does
-		 * not start with '/' or '.', then ftok() tries to interpret
-		 * the file path in MPE syntax instead of POSIX HFS syntax.
-		 * The workaround is to prepend "./" to these paths.  See HP
-		 * SR 5003416081 for details.
-		 */
-		if (*path != '/' && *path != '.') {
-			if (strlen(path) + strlen("./") + 1 > sizeof(mpe_path))
-				return (ENAMETOOLONG);
-			mpe_path[0] = '.';
-			mpe_path[1] = '/';
-			(void)strcpy(mpe_path + 2, path);
-			path = mpe_path;
-		}
-		}
-#endif
-		if ((key = ftok(path, 1)) == (key_t)-1)
-			return (errno);
-
-		shmflg = IPC_CREAT | 0600;
-		if ((infop->segid = shmget(key, infop->size, shmflg)) == -1)
-			return (errno);
-	}
+	if (F_ISSET(infop, REGION_CREATED) &&
+	   (infop->segid = shmget(0, infop->size, IPC_PRIVATE | 0600)) == -1)
+		return (errno);
 
 	if ((infop->addr = shmat(infop->segid, NULL, 0)) == (void *)-1) {
 		/*
diff --git a/db2/os/os_oflags.c b/db2/os/os_oflags.c
index 976b84d709..a4003dd5f0 100644
--- a/db2/os/os_oflags.c
+++ b/db2/os/os_oflags.c
@@ -44,7 +44,7 @@ __db_oflags(oflags)
 	case O_RDWR:
 		break;
 	default:		/* Bogus flags value from user.  */
-	  /* XXX no way to return error from here */
+		/* XXX no way to return error from here */
 	}
 	if (oflags & O_CREAT)
 		dbflags |= DB_CREATE;
diff --git a/db2/os/os_open.c b/db2/os/os_open.c
index e960377ebb..c54fd7365d 100644
--- a/db2/os/os_open.c
+++ b/db2/os/os_open.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_open.c	10.26 (Sleepycat) 5/4/98";
+static const char sccsid[] = "@(#)os_open.c	10.33 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -16,10 +16,12 @@ static const char sccsid[] = "@(#)os_open.c	10.26 (Sleepycat) 5/4/98";
 
 #include <errno.h>
 #include <fcntl.h>
+#include <signal.h>
 #include <unistd.h>
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
  * __db_open --
@@ -33,7 +35,10 @@ __db_open(name, arg_flags, ok_flags, mode, fdp)
 	u_int32_t arg_flags, ok_flags;
 	int mode, *fdp;
 {
-	int fd, flags;
+#if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
+	sigset_t set, oset;
+#endif
+	int flags, ret;
 
 	if (arg_flags & ~ok_flags)
 		return (EINVAL);
@@ -71,41 +76,77 @@ __db_open(name, arg_flags, ok_flags, mode, fdp)
 	if (arg_flags & DB_TRUNCATE)
 		flags |= O_TRUNC;
 
+#if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
+	/*
+	 * We block every signal we can get our hands on so that the temporary
+	 * file isn't left around if we're interrupted at the wrong time.  Of
+	 * course, if we drop core in-between the calls we'll hang forever, but
+	 * that's probably okay.  ;-)
+	 */
+	if (arg_flags & DB_TEMPORARY) {
+		(void)sigfillset(&set);
+		(void)sigprocmask(SIG_BLOCK, &set, &oset);
+	}
+#endif
+
 	/* Open the file. */
-	if ((fd = __os_open(name, flags, mode)) == -1)
-		return (errno);
+	if ((ret = __os_open(name, flags, mode, fdp)) != 0)
+		return (ret);
 
-#ifndef _WIN32
+#if !defined(_WIN32)
 	/* Delete any temporary file; done for Win32 by _O_TEMPORARY. */
-	if (arg_flags & DB_TEMPORARY)
+	if (arg_flags & DB_TEMPORARY) {
 		(void)__os_unlink(name);
+#if defined(HAVE_SIGFILLSET)
+		(void)sigprocmask(SIG_SETMASK, &oset, NULL);
+#endif
+	}
 #endif
 
-#if !defined(_WIN32) && !defined(WIN16)
+#if !defined(_WIN32) && !defined(WIN16) && !defined(VMS)
 	/*
-	 * Deny access to any child process; done for Win32 by O_NOINHERIT,
-	 * MacOS has neither child processes nor fd inheritance.
+	 * Deny access to any child process.
+	 *	VMS: does not have fd inheritance.
+	 *	Win32: done by O_NOINHERIT.
 	 */
-	if (fcntl(fd, F_SETFD, 1) == -1) {
-		int ret = errno;
+	if (fcntl(*fdp, F_SETFD, 1) == -1) {
+		ret = errno;
 
-		(void)__os_close(fd);
+		(void)__os_close(*fdp);
 		return (ret);
 	}
 #endif
-	*fdp = fd;
 	return (0);
 }
 
 /*
- * __db_close --
+ * __os_open --
+ *	Open a file.
+ *
+ * PUBLIC: int __os_open __P((const char *, int, int, int *));
+ */
+int
+__os_open(name, flags, mode, fdp)
+	const char *name;
+	int flags, mode, *fdp;
+{
+	*fdp = __db_jump.j_open != NULL ?
+	    __db_jump.j_open(name, flags, mode) : open(name, flags, mode);
+	return (*fdp == -1 ? errno : 0);
+}
+
+/*
+ * __os_close --
  *	Close a file descriptor.
  *
- * PUBLIC: int __db_close __P((int));
+ * PUBLIC: int __os_close __P((int));
  */
 int
-__db_close(fd)
+__os_close(fd)
 	int fd;
 {
-	return (__os_close(fd) ? errno : 0);
+	int ret;
+
+	ret = __db_jump.j_close != NULL ? __db_jump.j_close(fd) : close(fd);
+	return (ret == 0 ? 0 : errno);
 }
diff --git a/db2/os/os_rw.c b/db2/os/os_rw.c
index 7591041981..38f5b9473a 100644
--- a/db2/os/os_rw.c
+++ b/db2/os/os_rw.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_rw.c	10.7 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)os_rw.c	10.11 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,15 +19,73 @@ static const char sccsid[] = "@(#)os_rw.c	10.7 (Sleepycat) 4/10/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
- * __db_read --
+ * __os_io --
+ *	Do an I/O.
+ *
+ * PUBLIC: int __os_io __P((DB_IO *, int, ssize_t *));
+ */
+int
+__os_io(db_iop, op, niop)
+	DB_IO *db_iop;
+	int op;
+	ssize_t *niop;
+{
+	int ret;
+
+#ifdef HAVE_PREAD
+	switch (op) {
+	case DB_IO_READ:
+		if (__db_jump.j_read != NULL)
+			goto slow;
+		*niop = pread(db_iop->fd_io, db_iop->buf,
+		    db_iop->bytes, (off_t)db_iop->pgno * db_iop->pagesize);
+		break;
+	case DB_IO_WRITE:
+		if (__db_jump.j_write != NULL)
+			goto slow;
+		*niop = pwrite(db_iop->fd_io, db_iop->buf,
+		    db_iop->bytes, (off_t)db_iop->pgno * db_iop->pagesize);
+		break;
+	}
+	if (*niop == db_iop->bytes)
+		return (0);
+slow:
+#endif
+	if (db_iop->mutexp != NULL)
+		(void)__db_mutex_lock(db_iop->mutexp, db_iop->fd_lock);
+
+	if ((ret = __os_seek(db_iop->fd_io,
+	    db_iop->pagesize, db_iop->pgno, 0, 0, SEEK_SET)) != 0)
+		goto err;
+	switch (op) {
+	case DB_IO_READ:
+		ret =
+		    __os_read(db_iop->fd_io, db_iop->buf, db_iop->bytes, niop);
+		break;
+	case DB_IO_WRITE:
+		ret =
+		    __os_write(db_iop->fd_io, db_iop->buf, db_iop->bytes, niop);
+		break;
+	}
+
+err:	if (db_iop->mutexp != NULL)
+		(void)__db_mutex_unlock(db_iop->mutexp, db_iop->fd_lock);
+
+	return (ret);
+
+}
+
+/*
+ * __os_read --
  *	Read from a file handle.
  *
- * PUBLIC: int __db_read __P((int, void *, size_t, ssize_t *));
+ * PUBLIC: int __os_read __P((int, void *, size_t, ssize_t *));
  */
 int
-__db_read(fd, addr, len, nrp)
+__os_read(fd, addr, len, nrp)
 	int fd;
 	void *addr;
 	size_t len;
@@ -39,7 +97,9 @@ __db_read(fd, addr, len, nrp)
 
 	for (taddr = addr,
 	    offset = 0; offset < len; taddr += nr, offset += nr) {
-		if ((nr = __os_read(fd, taddr, len - offset)) < 0)
+		if ((nr = __db_jump.j_read != NULL ?
+		    __db_jump.j_read(fd, taddr, len - offset) :
+		    read(fd, taddr, len - offset)) < 0)
 			return (errno);
 		if (nr == 0)
 			break;
@@ -49,15 +109,15 @@ __db_read(fd, addr, len, nrp)
 }
 
 /*
- * __db_write --
+ * __os_write --
  *	Write to a file handle.
  *
- * PUBLIC: int __db_write __P((int, void *, size_t, ssize_t *));
+ * PUBLIC: int __os_write __P((int, void *, size_t, ssize_t *));
  */
 int
-__db_write(fd, addr, len, nwp)
+__os_write(fd, addr, len, nwp)
 	int fd;
-	void *addr;
+	const void *addr;
 	size_t len;
 	ssize_t *nwp;
 {
@@ -67,7 +127,9 @@ __db_write(fd, addr, len, nwp)
 
 	for (taddr = addr,
 	    offset = 0; offset < len; taddr += nw, offset += nw)
-		if ((nw = __os_write(fd, taddr, len - offset)) < 0)
+		if ((nw = __db_jump.j_write != NULL ?
+		    __db_jump.j_write(fd, taddr, len - offset) :
+		    write(fd, taddr, len - offset)) < 0)
 			return (errno);
 	*nwp = len;
 	return (0);
diff --git a/db2/os/os_seek.c b/db2/os/os_seek.c
index 159425cc27..ae5272bd1c 100644
--- a/db2/os/os_seek.c
+++ b/db2/os/os_seek.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_seek.c	10.9 (Sleepycat) 4/19/98";
+static const char sccsid[] = "@(#)os_seek.c	10.11 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,6 +19,7 @@ static const char sccsid[] = "@(#)os_seek.c	10.9 (Sleepycat) 4/19/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
  * __os_seek --
@@ -35,10 +36,17 @@ __os_seek(fd, pgsize, pageno, relative, isrewind, whence)
 	int isrewind, whence;
 {
 	off_t offset;
-
-	offset = (off_t)pgsize * pageno + relative;
-	if (isrewind)
-		offset = -offset;
-
-	return (lseek(fd, offset, whence) == -1 ? errno : 0);
+	int ret;
+
+	if (__db_jump.j_seek != NULL)
+		ret = __db_jump.j_seek(fd,
+		    pgsize, pageno, relative, isrewind, whence);
+	else {
+		offset = (off_t)pgsize * pageno + relative;
+		if (isrewind)
+			offset = -offset;
+
+		ret = lseek(fd, offset, whence);
+	}
+	return (ret == -1 ? errno : 0);
 }
diff --git a/db2/os/os_sleep.c b/db2/os/os_sleep.c
index 6a5b91f5c4..5aa476352e 100644
--- a/db2/os/os_sleep.c
+++ b/db2/os/os_sleep.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_sleep.c	10.10 (Sleepycat) 4/27/98";
+static const char sccsid[] = "@(#)os_sleep.c	10.12 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -28,6 +28,7 @@ static const char sccsid[] = "@(#)os_sleep.c	10.10 (Sleepycat) 4/27/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
  * __os_sleep --
@@ -45,6 +46,9 @@ __os_sleep(secs, usecs)
 	for (; usecs >= 1000000; ++secs, usecs -= 1000000)
 		;
 
+	if (__db_jump.j_sleep != NULL)
+		return (__db_jump.j_sleep(secs, usecs));
+
 	/*
 	 * It's important that we yield the processor here so that other
 	 * processes or threads are permitted to run.
diff --git a/db2/os/os_spin.c b/db2/os/os_spin.c
index 2fd21d018b..cbde58894a 100644
--- a/db2/os/os_spin.c
+++ b/db2/os/os_spin.c
@@ -8,17 +8,50 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_spin.c	10.7 (Sleepycat) 5/20/98";
+static const char sccsid[] = "@(#)os_spin.c	10.10 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
 #include <sys/types.h>
+#if defined(HAVE_PSTAT_GETDYNAMIC)
+#include <sys/pstat.h>
+#endif
 
 #include <limits.h>
 #include <unistd.h>
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
+
+#if defined(HAVE_PSTAT_GETDYNAMIC)
+/*
+ * __os_pstat_getdynamic --
+ *	HP/UX.
+ */
+static int
+__os_pstat_getdynamic()
+{
+	struct pst_dynamic psd;
+
+	return (pstat_getdynamic(&psd,
+	    sizeof(psd), (size_t)1, 0) == -1 ? 1 : psd.psd_proc_cnt);
+}
+#endif
+
+#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
+/*
+ * __os_sysconf --
+ *	Solaris, Linux.
+ */
+static int
+__os_sysconf(void)
+{
+	int nproc;
+
+	return ((nproc = sysconf(_SC_NPROCESSORS_ONLN)) > 1 ? nproc : 1);
+}
+#endif
 
 /*
  * __os_spin --
@@ -29,33 +62,46 @@ static const char sccsid[] = "@(#)os_spin.c	10.7 (Sleepycat) 5/20/98";
 int
 __os_spin()
 {
-	static long sys_val;
-
-	/* If the application specified the spins, use its value. */
+	/*
+	 * If the application specified a value or we've already figured it
+	 * out, return it.
+	 *
+	 * XXX
+	 * We don't want to repeatedly call the underlying function because
+	 * it can be expensive (e.g., requiring multiple filesystem accesses
+	 * under Debian Linux).
+	 */
 	if (DB_GLOBAL(db_tsl_spins) != 0)
 		return (DB_GLOBAL(db_tsl_spins));
 
-	/* If we've already figured this out, return the value. */
-	if (sys_val != 0)
-		return (sys_val);
+	DB_GLOBAL(db_tsl_spins) = 1;
+#if defined(HAVE_PSTAT_GETDYNAMIC)
+	DB_GLOBAL(db_tsl_spins) = __os_pstat_getdynamic();
+#endif
+#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
+	DB_GLOBAL(db_tsl_spins) = __os_sysconf();
+#endif
 
 	/*
-	 * XXX
-	 * Solaris and Linux use _SC_NPROCESSORS_ONLN to return the number of
-	 * online processors.  We don't want to repeatedly call sysconf because
-	 * it's quite expensive (requiring multiple filesystem accesses) under
-	 * Debian Linux.
-	 *
-	 * Spin 50 times per processor -- we have anecdotal evidence that this
+	 * Spin 50 times per processor, we have anecdotal evidence that this
 	 * is a reasonable value.
 	 */
-#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
-	if ((sys_val = sysconf(_SC_NPROCESSORS_ONLN)) > 1)
-		sys_val *= 50;
-	else
-		sys_val = 1;
-#else
-	sys_val = 1;
-#endif
-	return (sys_val);
+	DB_GLOBAL(db_tsl_spins) *= 50;
+
+	return (DB_GLOBAL(db_tsl_spins));
+}
+
+/*
+ * __os_yield --
+ *	Yield the processor.
+ *
+ * PUBLIC: void __os_yield __P((u_long));
+ */
+void
+__os_yield(usecs)
+	u_long usecs;
+{
+	if (__db_jump.j_yield != NULL && __db_jump.j_yield() == 0)
+		return;
+	__os_sleep(0, usecs);
 }
diff --git a/db2/os/os_stat.c b/db2/os/os_stat.c
index e7d3f24174..65cba82efa 100644
--- a/db2/os/os_stat.c
+++ b/db2/os/os_stat.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_stat.c	10.15 (Sleepycat) 4/27/98";
+static const char sccsid[] = "@(#)os_stat.c	10.18 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,6 +19,7 @@ static const char sccsid[] = "@(#)os_stat.c	10.15 (Sleepycat) 4/27/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
  * __os_exists --
@@ -33,6 +34,9 @@ __os_exists(path, isdirp)
 {
 	struct stat sb;
 
+	if (__db_jump.j_exists != NULL)
+		return (__db_jump.j_exists(path, isdirp));
+
 	if (stat(path, &sb) != 0)
 		return (errno);
 
@@ -65,7 +69,8 @@ __os_ioinfo(path, fd, mbytesp, bytesp, iosizep)
 {
 	struct stat sb;
 
-	COMPQUIET(path, NULL);
+	if (__db_jump.j_ioinfo != NULL)
+		return (__db_jump.j_ioinfo(path, fd, mbytesp, bytesp, iosizep));
 
 	if (fstat(fd, &sb) == -1)
 		return (errno);
@@ -80,7 +85,7 @@ __os_ioinfo(path, fd, mbytesp, bytesp, iosizep)
 	 * Return the underlying filesystem blocksize, if available.
 	 *
 	 * XXX
-	 * Check for a 0 size -- HP's MPE architecture has st_blksize,
+	 * Check for a 0 size -- the HP MPE/iX architecture has st_blksize,
 	 * but it's always 0.
 	 */
 #ifdef HAVE_ST_BLKSIZE
diff --git a/db2/os/os_tmpdir.c b/db2/os/os_tmpdir.c
new file mode 100644
index 0000000000..0b0bbc7c61
--- /dev/null
+++ b/db2/os/os_tmpdir.c
@@ -0,0 +1,113 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998
+ *	Sleepycat Software.  All rights reserved.
+ */
+
+#include "config.h"
+
+#ifndef lint
+static const char sccsid[] = "@(#)os_tmpdir.c	10.3 (Sleepycat) 10/13/98";
+#endif /* not lint */
+
+#ifndef NO_SYSTEM_INCLUDES
+#include <sys/types.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#endif
+
+#include "db_int.h"
+#include "common_ext.h"
+
+#ifdef macintosh
+#include <TFileSpec.h>
+#endif
+
+/*
+ * __os_tmpdir --
+ *	Set the temporary directory path.
+ *
+ * The order of items in the list structure and the order of checks in
+ * the environment are documented.
+ *
+ * PUBLIC: int __os_tmpdir __P((DB_ENV *, u_int32_t));
+ */
+int
+__os_tmpdir(dbenv, flags)
+	DB_ENV *dbenv;
+	u_int32_t flags;
+{
+	/*
+	 * !!!
+	 * Don't change this to:
+	 *
+	 *	static const char * const list[]
+	 *
+	 * because it creates a text relocation in position independent code.
+	 */
+	static const char * list[] = {
+		"/var/tmp",
+		"/usr/tmp",
+		"/temp",		/* Windows. */
+		"/tmp",
+		"C:/temp",		/* Windows. */
+		"C:/tmp",		/* Windows. */
+		NULL
+	};
+	const char * const *lp, *p;
+
+	/* Use the environment if it's permitted and initialized. */
+	p = NULL;
+#ifdef HAVE_GETEUID
+	if (LF_ISSET(DB_USE_ENVIRON) ||
+	    (LF_ISSET(DB_USE_ENVIRON_ROOT) && getuid() == 0))
+#else
+	if (LF_ISSET(DB_USE_ENVIRON))
+#endif
+	{
+		if ((p = getenv("TMPDIR")) != NULL && p[0] == '\0') {
+			__db_err(dbenv, "illegal TMPDIR environment variable");
+			return (EINVAL);
+		}
+		/* Windows */
+		if (p == NULL && (p = getenv("TEMP")) != NULL && p[0] == '\0') {
+			__db_err(dbenv, "illegal TEMP environment variable");
+			return (EINVAL);
+		}
+		/* Windows */
+		if (p == NULL && (p = getenv("TMP")) != NULL && p[0] == '\0') {
+			__db_err(dbenv, "illegal TMP environment variable");
+			return (EINVAL);
+		}
+		/* Macintosh */
+		if (p == NULL &&
+		    (p = getenv("TempFolder")) != NULL && p[0] == '\0') {
+			__db_err(dbenv,
+			    "illegal TempFolder environment variable");
+			return (EINVAL);
+		}
+	}
+
+#ifdef macintosh
+	/* Get the path to the temporary folder. */
+	if (p == NULL) {
+		FSSpec spec;
+
+		if (!Special2FSSpec(kTemporaryFolderType,
+		    kOnSystemDisk, 0, &spec))
+			(void)__os_strdup(FSp2FullPath(&spec), &p);
+	}
+#endif
+
+	/* Step through the list looking for a possibility. */
+	if (p == NULL)
+		for (lp = list; *lp != NULL; ++lp)
+			if (__os_exists(p = *lp, NULL) == 0)
+				break;
+	if (p == NULL)
+		return (0);
+
+	return (__os_strdup(p, &dbenv->db_tmp_dir));
+}
diff --git a/db2/os/os_unlink.c b/db2/os/os_unlink.c
index 3a1fa3ff99..aa484de843 100644
--- a/db2/os/os_unlink.c
+++ b/db2/os/os_unlink.c
@@ -8,7 +8,7 @@
 #include "config.h"
 
 #ifndef lint
-static const char sccsid[] = "@(#)os_unlink.c	10.5 (Sleepycat) 4/10/98";
+static const char sccsid[] = "@(#)os_unlink.c	10.7 (Sleepycat) 10/12/98";
 #endif /* not lint */
 
 #ifndef NO_SYSTEM_INCLUDES
@@ -19,16 +19,21 @@ static const char sccsid[] = "@(#)os_unlink.c	10.5 (Sleepycat) 4/10/98";
 #endif
 
 #include "db_int.h"
+#include "os_jump.h"
 
 /*
- * __db_unlink --
+ * __os_unlink --
  *	Remove a file.
  *
- * PUBLIC: int __db_unlink __P((const char *));
+ * PUBLIC: int __os_unlink __P((const char *));
  */
 int
-__db_unlink(path)
+__os_unlink(path)
 	const char *path;
 {
-	return (__os_unlink(path) == -1 ? errno : 0);
+	int ret;
+
+	ret = __db_jump.j_unlink != NULL ?
+	    __db_jump.j_unlink(path) : unlink(path);
+	return (ret == -1 ? errno : 0);
 }