1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997,2008 Oracle.  All rights reserved.
5 *
6 * $Id: os_seek.c,v 12.15 2008/01/08 20:58:46 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * __os_seek --
15 *	Seek to a page/byte offset in the file.
16 */
17int
18__os_seek(env, fhp, pgno, pgsize, relative)
19	ENV *env;
20	DB_FH *fhp;
21	db_pgno_t pgno;
22	u_int32_t pgsize;
23	u_int32_t relative;
24{
25	/* Yes, this really is how Microsoft designed their API. */
26	union {
27		__int64 bigint;
28		struct {
29			unsigned long low;
30			long high;
31		};
32	} offbytes;
33	DB_ENV *dbenv;
34	off_t offset;
35	int ret;
36
37	dbenv = env == NULL ? NULL : env->dbenv;
38
39#if defined(HAVE_STATISTICS)
40	++fhp->seek_count;
41#endif
42
43	offset = (off_t)pgsize * pgno + relative;
44
45	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
46		__db_msg(env,
47		    "fileops: seek %s to %lu", fhp->name, (u_long)offset);
48
49	offbytes.bigint = offset;
50	ret = (SetFilePointer(fhp->handle, offbytes.low,
51	    &offbytes.high, FILE_BEGIN) == (DWORD)-1) ? __os_get_syserr() : 0;
52
53	if (ret == 0) {
54		fhp->pgsize = pgsize;
55		fhp->pgno = pgno;
56		fhp->offset = relative;
57	} else {
58		__db_syserr(env, ret,
59		    "seek: %lu: (%lu * %lu) + %lu", (u_long)offset,
60		    (u_long)pgno, (u_long)pgsize, (u_long)relative);
61		ret = __os_posix_err(ret);
62	}
63
64	return (ret);
65}
66