1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2006,2008 Oracle.  All rights reserved.
5 *
6 * $Id: fopen.c,v 1.5 2008/01/08 20:58:44 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13/*
14 * fopen --
15 *
16 * PUBLIC: #ifndef HAVE_FOPEN
17 * PUBLIC: FILE *fopen __P((const char *, const char *));
18 * PUBLIC: #endif
19 */
20FILE *
21fopen(filename, mode)
22	const char *filename, *mode;
23{
24	IFile *pIFile;
25	IFileMgr *pIFileMgr;
26	OpenFileMode flags;
27	int f_exists, ret, update_flag;
28
29	/*
30	 * Note: files are created with read/write privilege.
31	 *
32	 * Upon successful completion, fopen() returns a pointer to the
33	 * object controlling the stream.  Otherwise, NULL is returned,
34	 * and errno is set to indicate the error.
35	 */
36	DB_ASSERT(NULL, filename != NULL && mode != NULL);
37
38	FILE_MANAGER_CREATE(NULL, pIFileMgr, ret);
39	if (ret != 0) {
40		__os_set_errno(ret);
41		return (NULL);
42	}
43
44	/*
45	 * The argument mode points to a string beginning with one of the
46	 * following sequences:
47	 * r or rb
48	 *	Open file for reading.
49	 * w or wb
50	 *	Truncate to zero length or create file for writing.
51	 * a or ab
52	 *	Append; open or create file for writing at end-of-file.
53	 * r+ or rb+ or r+b
54	 *	Open file for update (reading and writing).
55	 * w+ or wb+ or w+b
56	 *	Truncate to zero length or create file for update.
57	 * a+ or ab+ or a+b
58	 *	Append; open or create file for update, writing at end-of-file.
59	 */
60	flags = 0;
61	update_flag = strchr(mode, '+') ? 1 : 0;
62	switch (*mode) {
63	case 'a':			/* append mode */
64		flags = _OFM_APPEND | _OFM_CREATE;
65		break;
66	case 'r':			/* read mode */
67		flags = update_flag ? _OFM_READWRITE : _OFM_READ;
68		break;
69	case 'w':			/* write mode */
70		flags = _OFM_READWRITE | _OFM_CREATE;
71		break;
72	}
73
74	f_exists = IFILEMGR_Test(pIFileMgr, filename) == SUCCESS ? 1 : 0;
75	if (f_exists)
76		LF_CLR(_OFM_CREATE);		/* Clear _OFM_CREATE. */
77	else
78		LF_CLR(~_OFM_CREATE);		/* Leave only _OFM_CREATE. */
79
80	if ((pIFile = IFILEMGR_OpenFile(
81	    pIFileMgr, filename, (OpenFileMode)flags)) == NULL) {
82		FILE_MANAGER_ERR(NULL,
83		    pIFileMgr, filename, "IFILEMGR_OpenFile", ret);
84		__os_set_errno(ret);
85	}
86
87	IFILEMGR_Release(pIFileMgr);
88	return (pIFile);
89}
90