Blame src/plugins/kdb/db2/libdb2/btree/bt_open.c

Packit fd8b60
/*-
Packit fd8b60
 * Copyright (c) 1990, 1993, 1994
Packit fd8b60
 *	The Regents of the University of California.  All rights reserved.
Packit fd8b60
 *
Packit fd8b60
 * This code is derived from software contributed to Berkeley by
Packit fd8b60
 * Mike Olson.
Packit fd8b60
 *
Packit fd8b60
 * Redistribution and use in source and binary forms, with or without
Packit fd8b60
 * modification, are permitted provided that the following conditions
Packit fd8b60
 * are met:
Packit fd8b60
 * 1. Redistributions of source code must retain the above copyright
Packit fd8b60
 *    notice, this list of conditions and the following disclaimer.
Packit fd8b60
 * 2. Redistributions in binary form must reproduce the above copyright
Packit fd8b60
 *    notice, this list of conditions and the following disclaimer in the
Packit fd8b60
 *    documentation and/or other materials provided with the distribution.
Packit fd8b60
 * 3. All advertising materials mentioning features or use of this software
Packit fd8b60
 *    must display the following acknowledgement:
Packit fd8b60
 *	This product includes software developed by the University of
Packit fd8b60
 *	California, Berkeley and its contributors.
Packit fd8b60
 * 4. Neither the name of the University nor the names of its contributors
Packit fd8b60
 *    may be used to endorse or promote products derived from this software
Packit fd8b60
 *    without specific prior written permission.
Packit fd8b60
 *
Packit fd8b60
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit fd8b60
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit fd8b60
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit fd8b60
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit fd8b60
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit fd8b60
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit fd8b60
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit fd8b60
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit fd8b60
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit fd8b60
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit fd8b60
 * SUCH DAMAGE.
Packit fd8b60
 */
Packit fd8b60
Packit fd8b60
#if defined(LIBC_SCCS) && !defined(lint)
Packit fd8b60
static char sccsid[] = "@(#)bt_open.c	8.11 (Berkeley) 11/2/95";
Packit fd8b60
#endif /* LIBC_SCCS and not lint */
Packit fd8b60
Packit fd8b60
/*
Packit fd8b60
 * Implementation of btree access method for 4.4BSD.
Packit fd8b60
 *
Packit fd8b60
 * The design here was originally based on that of the btree access method
Packit fd8b60
 * used in the Postgres database system at UC Berkeley.  This implementation
Packit fd8b60
 * is wholly independent of the Postgres code.
Packit fd8b60
 */
Packit fd8b60
Packit fd8b60
#include "k5-platform.h"
Packit fd8b60
Packit fd8b60
#include <sys/param.h>
Packit fd8b60
#include <sys/stat.h>
Packit fd8b60
Packit fd8b60
#include <errno.h>
Packit fd8b60
#include <fcntl.h>
Packit fd8b60
#include <limits.h>
Packit fd8b60
#include <signal.h>
Packit fd8b60
#include <stdio.h>
Packit fd8b60
#include <stdlib.h>
Packit fd8b60
#include <string.h>
Packit fd8b60
#include <unistd.h>
Packit fd8b60
Packit fd8b60
#include "db-int.h"
Packit fd8b60
#include "btree.h"
Packit fd8b60
Packit fd8b60
#ifdef DEBUG
Packit fd8b60
#undef	MINPSIZE
Packit fd8b60
#define	MINPSIZE	128
Packit fd8b60
#endif
Packit fd8b60
Packit fd8b60
static int byteorder __P((void));
Packit fd8b60
static int nroot __P((BTREE *));
Packit fd8b60
static int tmp __P((void));
Packit fd8b60
Packit fd8b60
/*
Packit fd8b60
 * __BT_OPEN -- Open a btree.
Packit fd8b60
 *
Packit fd8b60
 * Creates and fills a DB struct, and calls the routine that actually
Packit fd8b60
 * opens the btree.
Packit fd8b60
 *
Packit fd8b60
 * Parameters:
Packit fd8b60
 *	fname:	filename (NULL for in-memory trees)
Packit fd8b60
 *	flags:	open flag bits
Packit fd8b60
 *	mode:	open permission bits
Packit fd8b60
 *	b:	BTREEINFO pointer
Packit fd8b60
 *
Packit fd8b60
 * Returns:
Packit fd8b60
 *	NULL on failure, pointer to DB on success.
Packit fd8b60
 *
Packit fd8b60
 */
Packit fd8b60
DB *
Packit fd8b60
__bt_open(fname, flags, mode, openinfo, dflags)
Packit fd8b60
	const char *fname;
Packit fd8b60
	int flags, mode, dflags;
Packit fd8b60
	const BTREEINFO *openinfo;
Packit fd8b60
{
Packit fd8b60
	struct stat sb;
Packit fd8b60
	BTMETA m;
Packit fd8b60
	BTREE *t;
Packit fd8b60
	BTREEINFO b;
Packit fd8b60
	DB *dbp;
Packit fd8b60
	db_pgno_t ncache;
Packit fd8b60
	ssize_t nr;
Packit fd8b60
	int machine_lorder;
Packit fd8b60
Packit fd8b60
	t = NULL;
Packit fd8b60
Packit fd8b60
	/*
Packit fd8b60
	 * Intention is to make sure all of the user's selections are okay
Packit fd8b60
	 * here and then use them without checking.  Can't be complete, since
Packit fd8b60
	 * we don't know the right page size, lorder or flags until the backing
Packit fd8b60
	 * file is opened.  Also, the file's page size can cause the cachesize
Packit fd8b60
	 * to change.
Packit fd8b60
	 */
Packit fd8b60
	machine_lorder = byteorder();
Packit fd8b60
	if (openinfo) {
Packit fd8b60
		b = *openinfo;
Packit fd8b60
Packit fd8b60
		/* Flags: R_DUP. */
Packit fd8b60
		if (b.flags & ~(R_DUP))
Packit fd8b60
			goto einval;
Packit fd8b60
Packit fd8b60
		/*
Packit fd8b60
		 * Page size must be indx_t aligned and >= MINPSIZE.  Default
Packit fd8b60
		 * page size is set farther on, based on the underlying file
Packit fd8b60
		 * transfer size.
Packit fd8b60
		 */
Packit fd8b60
		if (b.psize &&
Packit fd8b60
		    (b.psize < MINPSIZE || b.psize > MAX_PAGE_OFFSET + 1 ||
Packit fd8b60
		    b.psize & (sizeof(indx_t) - 1)))
Packit fd8b60
			goto einval;
Packit fd8b60
Packit fd8b60
		/* Minimum number of keys per page; absolute minimum is 2. */
Packit fd8b60
		if (b.minkeypage) {
Packit fd8b60
			if (b.minkeypage < 2)
Packit fd8b60
				goto einval;
Packit fd8b60
		} else
Packit fd8b60
			b.minkeypage = DEFMINKEYPAGE;
Packit fd8b60
Packit fd8b60
		/* If no comparison, use default comparison and prefix. */
Packit fd8b60
		if (b.compare == NULL) {
Packit fd8b60
			b.compare = __bt_defcmp;
Packit fd8b60
			if (b.prefix == NULL)
Packit fd8b60
				b.prefix = __bt_defpfx;
Packit fd8b60
		}
Packit fd8b60
Packit fd8b60
		if (b.lorder == 0)
Packit fd8b60
			b.lorder = machine_lorder;
Packit fd8b60
	} else {
Packit fd8b60
		b.compare = __bt_defcmp;
Packit fd8b60
		b.cachesize = 0;
Packit fd8b60
		b.flags = 0;
Packit fd8b60
		b.lorder = machine_lorder;
Packit fd8b60
		b.minkeypage = DEFMINKEYPAGE;
Packit fd8b60
		b.prefix = __bt_defpfx;
Packit fd8b60
		b.psize = 0;
Packit fd8b60
	}
Packit fd8b60
Packit fd8b60
	/* Check for the ubiquitous PDP-11. */
Packit fd8b60
	if (b.lorder != DB_BIG_ENDIAN && b.lorder != DB_LITTLE_ENDIAN)
Packit fd8b60
		goto einval;
Packit fd8b60
Packit fd8b60
	/* Allocate and initialize DB and BTREE structures. */
Packit fd8b60
	if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
Packit fd8b60
		goto err;
Packit fd8b60
	memset(t, 0, sizeof(BTREE));
Packit fd8b60
	t->bt_fd = -1;			/* Don't close unopened fd on error. */
Packit fd8b60
	t->bt_lorder = b.lorder;
Packit fd8b60
	t->bt_order = NOT;
Packit fd8b60
	t->bt_cmp = b.compare;
Packit fd8b60
	t->bt_pfx = b.prefix;
Packit fd8b60
	t->bt_rfd = -1;
Packit fd8b60
Packit fd8b60
	if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
Packit fd8b60
		goto err;
Packit fd8b60
	memset(t->bt_dbp, 0, sizeof(DB));
Packit fd8b60
	if (t->bt_lorder != machine_lorder)
Packit fd8b60
		F_SET(t, B_NEEDSWAP);
Packit fd8b60
Packit fd8b60
	dbp->type = DB_BTREE;
Packit fd8b60
	dbp->internal = t;
Packit fd8b60
	dbp->close = __bt_close;
Packit fd8b60
	dbp->del = __bt_delete;
Packit fd8b60
	dbp->fd = __bt_fd;
Packit fd8b60
	dbp->get = __bt_get;
Packit fd8b60
	dbp->put = __bt_put;
Packit fd8b60
	dbp->seq = __bt_seq;
Packit fd8b60
	dbp->sync = __bt_sync;
Packit fd8b60
Packit fd8b60
	/*
Packit fd8b60
	 * If no file name was supplied, this is an in-memory btree and we
Packit fd8b60
	 * open a backing temporary file.  Otherwise, it's a disk-based tree.
Packit fd8b60
	 */
Packit fd8b60
	if (fname) {
Packit fd8b60
		switch (flags & O_ACCMODE) {
Packit fd8b60
		case O_RDONLY:
Packit fd8b60
			F_SET(t, B_RDONLY);
Packit fd8b60
			break;
Packit fd8b60
		case O_RDWR:
Packit fd8b60
			break;
Packit fd8b60
		case O_WRONLY:
Packit fd8b60
		default:
Packit fd8b60
			goto einval;
Packit fd8b60
		}
Packit fd8b60
Packit Bot 805b76
		if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0)
Packit fd8b60
			goto err;
Packit fd8b60
Packit fd8b60
	} else {
Packit fd8b60
		if ((flags & O_ACCMODE) != O_RDWR)
Packit fd8b60
			goto einval;
Packit fd8b60
		if ((t->bt_fd = tmp()) == -1)
Packit fd8b60
			goto err;
Packit fd8b60
		F_SET(t, B_INMEM);
Packit fd8b60
	}
Packit fd8b60
Packit fd8b60
	if (fcntl(t->bt_fd, F_SETFD, 1) == -1)
Packit fd8b60
		goto err;
Packit fd8b60
Packit fd8b60
	if (fstat(t->bt_fd, &sb))
Packit fd8b60
		goto err;
Packit fd8b60
	if (sb.st_size) {
Packit fd8b60
		if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
Packit fd8b60
			goto err;
Packit fd8b60
		if (nr != sizeof(BTMETA))
Packit fd8b60
			goto eftype;
Packit fd8b60
Packit fd8b60
		/*
Packit fd8b60
		 * Read in the meta-data.  This can change the notion of what
Packit fd8b60
		 * the lorder, page size and flags are, and, when the page size
Packit fd8b60
		 * changes, the cachesize value can change too.  If the user
Packit fd8b60
		 * specified the wrong byte order for an existing database, we
Packit fd8b60
		 * don't bother to return an error, we just clear the NEEDSWAP
Packit fd8b60
		 * bit.
Packit fd8b60
		 */
Packit fd8b60
		if (m.magic == BTREEMAGIC)
Packit fd8b60
			F_CLR(t, B_NEEDSWAP);
Packit fd8b60
		else {
Packit fd8b60
			F_SET(t, B_NEEDSWAP);
Packit fd8b60
			M_32_SWAP(m.magic);
Packit fd8b60
			M_32_SWAP(m.version);
Packit fd8b60
			M_32_SWAP(m.psize);
Packit fd8b60
			M_32_SWAP(m.free);
Packit fd8b60
			M_32_SWAP(m.nrecs);
Packit fd8b60
			M_32_SWAP(m.flags);
Packit fd8b60
		}
Packit fd8b60
		if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
Packit fd8b60
			goto eftype;
Packit fd8b60
		if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
Packit fd8b60
		    m.psize & (sizeof(indx_t) - 1))
Packit fd8b60
			goto eftype;
Packit fd8b60
		if (m.flags & ~SAVEMETA)
Packit fd8b60
			goto eftype;
Packit fd8b60
		b.psize = m.psize;
Packit fd8b60
		F_SET(t, m.flags);
Packit fd8b60
		t->bt_free = m.free;
Packit fd8b60
		t->bt_nrecs = m.nrecs;
Packit fd8b60
	} else {
Packit fd8b60
		/*
Packit fd8b60
		 * Set the page size to the best value for I/O to this file.
Packit fd8b60
		 * Don't overflow the page offset type.
Packit fd8b60
		 */
Packit fd8b60
		if (b.psize == 0) {
Packit fd8b60
			b.psize = sb.st_blksize;
Packit fd8b60
			if (b.psize < MINPSIZE)
Packit fd8b60
				b.psize = MINPSIZE;
Packit fd8b60
			if (b.psize > MAX_PAGE_OFFSET + 1)
Packit fd8b60
				b.psize = MAX_PAGE_OFFSET + 1;
Packit fd8b60
		}
Packit fd8b60
Packit fd8b60
		/* Set flag if duplicates permitted. */
Packit fd8b60
		if (!(b.flags & R_DUP))
Packit fd8b60
			F_SET(t, B_NODUPS);
Packit fd8b60
Packit fd8b60
		t->bt_free = P_INVALID;
Packit fd8b60
		t->bt_nrecs = 0;
Packit fd8b60
		F_SET(t, B_METADIRTY);
Packit fd8b60
	}
Packit fd8b60
Packit fd8b60
	t->bt_psize = b.psize;
Packit fd8b60
Packit fd8b60
	/* Set the cache size; must be a multiple of the page size. */
Packit fd8b60
	if (b.cachesize && b.cachesize & (b.psize - 1))
Packit fd8b60
		b.cachesize += (~b.cachesize & (b.psize - 1)) + 1;
Packit fd8b60
	if (b.cachesize < b.psize * MINCACHE)
Packit fd8b60
		b.cachesize = b.psize * MINCACHE;
Packit fd8b60
Packit fd8b60
	/* Calculate number of pages to cache. */
Packit fd8b60
	ncache = (b.cachesize + t->bt_psize - 1) / t->bt_psize;
Packit fd8b60
Packit fd8b60
	/*
Packit fd8b60
	 * The btree data structure requires that at least two keys can fit on
Packit fd8b60
	 * a page, but other than that there's no fixed requirement.  The user
Packit fd8b60
	 * specified a minimum number per page, and we translated that into the
Packit fd8b60
	 * number of bytes a key/data pair can use before being placed on an
Packit fd8b60
	 * overflow page.  This calculation includes the page header, the size
Packit fd8b60
	 * of the index referencing the leaf item and the size of the leaf item
Packit fd8b60
	 * structure.  Also, don't let the user specify a minkeypage such that
Packit fd8b60
	 * a key/data pair won't fit even if both key and data are on overflow
Packit fd8b60
	 * pages.
Packit fd8b60
	 */
Packit fd8b60
	t->bt_ovflsize = (t->bt_psize - BTDATAOFF) / b.minkeypage -
Packit fd8b60
	    (sizeof(indx_t) + NBLEAFDBT(0, 0));
Packit fd8b60
	if (t->bt_ovflsize < NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t))
Packit fd8b60
		t->bt_ovflsize =
Packit fd8b60
		    NBLEAFDBT(NOVFLSIZE, NOVFLSIZE) + sizeof(indx_t);
Packit fd8b60
Packit fd8b60
	/* Initialize the buffer pool. */
Packit fd8b60
	if ((t->bt_mp =
Packit fd8b60
	    mpool_open(NULL, t->bt_fd, t->bt_psize, ncache)) == NULL)
Packit fd8b60
		goto err;
Packit fd8b60
	if (!F_ISSET(t, B_INMEM))
Packit fd8b60
		mpool_filter(t->bt_mp, __bt_pgin, __bt_pgout, t);
Packit fd8b60
Packit fd8b60
	/* Create a root page if new tree. */
Packit fd8b60
	if (nroot(t) == RET_ERROR)
Packit fd8b60
		goto err;
Packit fd8b60
Packit fd8b60
	/* Global flags. */
Packit fd8b60
	if (dflags & DB_LOCK)
Packit fd8b60
		F_SET(t, B_DB_LOCK);
Packit fd8b60
	if (dflags & DB_SHMEM)
Packit fd8b60
		F_SET(t, B_DB_SHMEM);
Packit fd8b60
	if (dflags & DB_TXN)
Packit fd8b60
		F_SET(t, B_DB_TXN);
Packit fd8b60
Packit fd8b60
	return (dbp);
Packit fd8b60
Packit fd8b60
einval:	errno = EINVAL;
Packit fd8b60
	goto err;
Packit fd8b60
Packit fd8b60
eftype:	errno = EFTYPE;
Packit fd8b60
	goto err;
Packit fd8b60
Packit fd8b60
err:	if (t) {
Packit fd8b60
		if (t->bt_dbp)
Packit fd8b60
			free(t->bt_dbp);
Packit fd8b60
		if (t->bt_fd != -1)
Packit fd8b60
			(void)close(t->bt_fd);
Packit fd8b60
		free(t);
Packit fd8b60
	}
Packit fd8b60
	return (NULL);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
/*
Packit fd8b60
 * NROOT -- Create the root of a new tree.
Packit fd8b60
 *
Packit fd8b60
 * Parameters:
Packit fd8b60
 *	t:	tree
Packit fd8b60
 *
Packit fd8b60
 * Returns:
Packit fd8b60
 *	RET_ERROR, RET_SUCCESS
Packit fd8b60
 */
Packit fd8b60
static int
Packit fd8b60
nroot(t)
Packit fd8b60
	BTREE *t;
Packit fd8b60
{
Packit fd8b60
	PAGE *meta, *root;
Packit fd8b60
	db_pgno_t npg;
Packit fd8b60
Packit fd8b60
	if ((root = mpool_get(t->bt_mp, 1, 0)) != NULL) {
Packit fd8b60
		if (root->lower == 0 &&
Packit fd8b60
		    root->pgno == 0 &&
Packit fd8b60
		    root->linp[0] == 0) {
Packit fd8b60
			mpool_delete(t->bt_mp, root);
Packit fd8b60
			errno = EINVAL;
Packit fd8b60
		} else {
Packit fd8b60
			mpool_put(t->bt_mp, root, 0);
Packit fd8b60
			return (RET_SUCCESS);
Packit fd8b60
		}
Packit fd8b60
	}
Packit fd8b60
	if (errno != EINVAL)		/* It's OK to not exist. */
Packit fd8b60
		return (RET_ERROR);
Packit fd8b60
	errno = 0;
Packit fd8b60
Packit fd8b60
	if ((meta = mpool_new(t->bt_mp, &npg, MPOOL_PAGE_NEXT)) == NULL)
Packit fd8b60
		return (RET_ERROR);
Packit fd8b60
Packit fd8b60
	if ((root = mpool_new(t->bt_mp, &npg, MPOOL_PAGE_NEXT)) == NULL)
Packit fd8b60
		return (RET_ERROR);
Packit fd8b60
Packit fd8b60
	if (npg != P_ROOT)
Packit fd8b60
		return (RET_ERROR);
Packit fd8b60
	root->pgno = npg;
Packit fd8b60
	root->prevpg = root->nextpg = P_INVALID;
Packit fd8b60
	root->lower = BTDATAOFF;
Packit fd8b60
	root->upper = t->bt_psize;
Packit fd8b60
	root->flags = P_BLEAF;
Packit fd8b60
	memset(meta, 0, t->bt_psize);
Packit fd8b60
	mpool_put(t->bt_mp, meta, MPOOL_DIRTY);
Packit fd8b60
	mpool_put(t->bt_mp, root, MPOOL_DIRTY);
Packit fd8b60
	return (RET_SUCCESS);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
static int
Packit fd8b60
tmp()
Packit fd8b60
{
Packit fd8b60
#ifdef SIG_BLOCK
Packit fd8b60
	sigset_t set, oset;
Packit fd8b60
#else
Packit fd8b60
	int oset;
Packit fd8b60
#endif
Packit fd8b60
	int fd;
Packit fd8b60
	char *envtmp;
Packit fd8b60
	char path[MAXPATHLEN];
Packit fd8b60
	static char fn[] = "/bt.XXXXXX";
Packit fd8b60
Packit fd8b60
	envtmp = getenv("TMPDIR");
Packit fd8b60
Packit fd8b60
	/* this used to be done with snprintf(), but since snprintf
Packit fd8b60
	   isn't in most operating systems, and overflow checking in
Packit fd8b60
	   this case is easy, this is what is done */
Packit fd8b60
Packit fd8b60
	if (envtmp && ((strlen(envtmp)+sizeof(fn)+1) > sizeof(path)))
Packit fd8b60
	    return(-1);
Packit fd8b60
Packit fd8b60
	(void)snprintf(path, sizeof(path),
Packit fd8b60
		       "%s%s", (envtmp ? envtmp : "/tmp"), fn);
Packit fd8b60
Packit fd8b60
#ifdef SIG_BLOCK
Packit fd8b60
	(void)sigfillset(&set);
Packit fd8b60
	(void)sigprocmask(SIG_BLOCK, &set, &oset);
Packit fd8b60
#else
Packit fd8b60
	oset = sigblock(~0);
Packit fd8b60
#endif
Packit fd8b60
	if ((fd = mkstemp(path)) != -1)
Packit fd8b60
		(void)unlink(path);
Packit fd8b60
	set_cloexec_fd(fd);
Packit fd8b60
#ifdef SIG_BLOCK
Packit fd8b60
	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
Packit fd8b60
#else
Packit fd8b60
	sigsetmask(oset);
Packit fd8b60
#endif
Packit fd8b60
#ifdef __CYGWIN32__
Packit fd8b60
      /* Ensure the fd is in binary mode. */
Packit fd8b60
      setmode(fd, O_BINARY);
Packit fd8b60
#endif /* __CYGWIN32__ */
Packit fd8b60
Packit fd8b60
	return(fd);
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
static int
Packit fd8b60
byteorder()
Packit fd8b60
{
Packit fd8b60
	u_int32_t x;
Packit fd8b60
	u_char *p;
Packit fd8b60
Packit fd8b60
	x = 0x01020304;
Packit fd8b60
	p = (u_char *)&x;
Packit fd8b60
	switch (*p) {
Packit fd8b60
	case 1:
Packit fd8b60
		return (DB_BIG_ENDIAN);
Packit fd8b60
	case 4:
Packit fd8b60
		return (DB_LITTLE_ENDIAN);
Packit fd8b60
	default:
Packit fd8b60
		return (0);
Packit fd8b60
	}
Packit fd8b60
}
Packit fd8b60
Packit fd8b60
int
Packit fd8b60
__bt_fd(dbp)
Packit fd8b60
        const DB *dbp;
Packit fd8b60
{
Packit fd8b60
	BTREE *t;
Packit fd8b60
Packit fd8b60
	t = dbp->internal;
Packit fd8b60
Packit fd8b60
	/* Toss any page pinned across calls. */
Packit fd8b60
	if (t->bt_pinned != NULL) {
Packit fd8b60
		mpool_put(t->bt_mp, t->bt_pinned, 0);
Packit fd8b60
		t->bt_pinned = NULL;
Packit fd8b60
	}
Packit fd8b60
Packit fd8b60
	/* In-memory database can't have a file descriptor. */
Packit fd8b60
	if (F_ISSET(t, B_INMEM)) {
Packit fd8b60
		errno = ENOENT;
Packit fd8b60
		return (-1);
Packit fd8b60
	}
Packit fd8b60
	return (t->bt_fd);
Packit fd8b60
}