1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997-2009 Oracle.  All rights reserved.
5 *
6 * $Id$
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * __os_exists --
15 *	Return if the file exists.
16 *
17 * PUBLIC: int __os_exists __P((ENV *, const char *, int *));
18 */
19int
20__os_exists(env, path, isdirp)
21	ENV *env;
22	const char *path;
23	int *isdirp;
24{
25	DB_ENV *dbenv;
26	struct stat sb;
27	int ret;
28
29	dbenv = env == NULL ? NULL : env->dbenv;
30
31	if (dbenv != NULL &&
32	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
33		__db_msg(env, "fileops: stat %s", path);
34
35	if (DB_GLOBAL(j_exists) != NULL)
36		return (DB_GLOBAL(j_exists)(path, isdirp));
37
38	RETRY_CHK((stat(CHAR_STAR_CAST path, &sb)), ret);
39	if (ret != 0)
40		return (__os_posix_err(ret));
41
42#if !defined(S_ISDIR) || defined(STAT_MACROS_BROKEN)
43#undef	S_ISDIR
44#ifdef _S_IFDIR
45#define	S_ISDIR(m)	(_S_IFDIR & (m))
46#else
47#define	S_ISDIR(m)	(((m) & 0170000) == 0040000)
48#endif
49#endif
50	if (isdirp != NULL)
51		*isdirp = S_ISDIR(sb.st_mode);
52
53	return (0);
54}
55
56/*
57 * __os_ioinfo --
58 *	Return file size and I/O size; abstracted to make it easier
59 *	to replace.
60 *
61 * PUBLIC: int __os_ioinfo __P((ENV *, const char *,
62 * PUBLIC:    DB_FH *, u_int32_t *, u_int32_t *, u_int32_t *));
63 */
64int
65__os_ioinfo(env, path, fhp, mbytesp, bytesp, iosizep)
66	ENV *env;
67	const char *path;
68	DB_FH *fhp;
69	u_int32_t *mbytesp, *bytesp, *iosizep;
70{
71	struct stat sb;
72	int ret;
73
74	if (DB_GLOBAL(j_ioinfo) != NULL)
75		return (DB_GLOBAL(j_ioinfo)(path,
76		    fhp->fd, mbytesp, bytesp, iosizep));
77
78	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
79
80	RETRY_CHK((fstat(fhp->fd, &sb)), ret);
81	if (ret != 0) {
82		__db_syserr(env, ret, "fstat");
83		return (__os_posix_err(ret));
84	}
85
86	/* Return the size of the file. */
87	if (mbytesp != NULL)
88		*mbytesp = (u_int32_t)(sb.st_size / MEGABYTE);
89	if (bytesp != NULL)
90		*bytesp = (u_int32_t)(sb.st_size % MEGABYTE);
91
92	/*
93	 * Return the underlying filesystem I/O size, if available.
94	 *
95	 * XXX
96	 * Check for a 0 size -- the HP MPE/iX architecture has st_blksize,
97	 * but it's always 0.
98	 */
99#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
100	if (iosizep != NULL && (*iosizep = sb.st_blksize) == 0)
101		*iosizep = DB_DEF_IOSIZE;
102#else
103	if (iosizep != NULL)
104		*iosizep = DB_DEF_IOSIZE;
105#endif
106	return (0);
107}
108