1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1998,2008 Oracle.  All rights reserved.
5 *
6 * $Id: os_handle.c,v 1.8 2008/01/31 18:40:46 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * __os_openhandle --
15 *      Open a file, using BREW open flags.
16 */
17int
18__os_openhandle(env, name, flags, mode, fhpp)
19	ENV *env;
20	const char *name;
21	int flags, mode;
22	DB_FH **fhpp;
23{
24	DB_FH *fhp;
25	IFile *pIFile;
26	IFileMgr *pIFileMgr;
27	int f_exists, ret;
28
29	COMPQUIET(mode, 0);
30
31	FILE_MANAGER_CREATE(env, pIFileMgr, ret);
32	if (ret != 0)
33		return (ret);
34
35	/*
36	 * Allocate the file handle and copy the file name.  We generally only
37	 * use the name for verbose or error messages, but on systems where we
38	 * can't unlink temporary files immediately, we use the name to unlink
39	 * the temporary file when the file handle is closed.
40	 */
41	if ((ret = __os_calloc(env, 1, sizeof(DB_FH), &fhp)) != 0)
42		return (ret);
43	if ((ret = __os_strdup(env, name, &fhp->name)) != 0)
44		goto err;
45
46	/*
47	 * Test the file before opening.  BREW doesn't want to see the
48	 * _OFM_CREATE flag if the file already exists, and it doesn't
49	 * want to see any other flag if the file doesn't exist.
50	 */
51	f_exists = IFILEMGR_Test(pIFileMgr, name) == SUCCESS ? 1 : 0;
52	if (f_exists)
53		LF_CLR(_OFM_CREATE);		/* Clear _OFM_CREATE. */
54	else
55		LF_CLR(~_OFM_CREATE);		/* Leave only _OFM_CREATE. */
56
57	if ((pIFile =
58	    IFILEMGR_OpenFile(pIFileMgr, name, (OpenFileMode)flags)) == NULL) {
59		FILE_MANAGER_ERR(env,
60		    pIFileMgr, name, "IFILEMGR_OpenFile", ret);
61		goto err;
62	}
63
64	fhp->ifp = pIFile;
65	IFILEMGR_Release(pIFileMgr);
66
67	F_SET(fhp, DB_FH_OPENED);
68	*fhpp = fhp;
69	return (0);
70
71err:	if (pIFile != NULL)
72		IFILE_Release(pIFile);
73	IFILEMGR_Release(pIFileMgr);
74
75	if (fhp != NULL)
76		(void)__os_closehandle(env, fhp);
77	return (ret);
78}
79
80/*
81 * __os_closehandle --
82 *      Close a file.
83 */
84int
85__os_closehandle(env, fhp)
86	ENV *env;
87	DB_FH *fhp;
88{
89	/* Discard any underlying system file reference. */
90	if (F_ISSET(fhp, DB_FH_OPENED))
91		(void)IFILE_Release(fhp->ifp);
92
93	/* Unlink the file if we haven't already done so. */
94	if (F_ISSET(fhp, DB_FH_UNLINK))
95		(void)__os_unlink(env, fhp->name, 0);
96
97	if (fhp->name != NULL)
98		__os_free(env, fhp->name);
99	__os_free(env, fhp);
100
101	return (0);
102}
103