about summary refs log tree commit diff
path: root/db2/os/os_open.c
blob: c54fd7365d45b805f6d47cc2433bb3bcea8640e5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*-
 * See the file LICENSE for redistribution information.
 *
 * Copyright (c) 1997, 1998
 *	Sleepycat Software.  All rights reserved.
 */

#include "config.h"

#ifndef lint
static const char sccsid[] = "@(#)os_open.c	10.33 (Sleepycat) 10/12/98";
#endif /* not lint */

#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#endif

#include "db_int.h"
#include "os_jump.h"

/*
 * __db_open --
 *	Open a file descriptor.
 *
 * PUBLIC: int __db_open __P((const char *, u_int32_t, u_int32_t, int, int *));
 */
int
__db_open(name, arg_flags, ok_flags, mode, fdp)
	const char *name;
	u_int32_t arg_flags, ok_flags;
	int mode, *fdp;
{
#if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
	sigset_t set, oset;
#endif
	int flags, ret;

	if (arg_flags & ~ok_flags)
		return (EINVAL);

	flags = 0;

	/*
	 * DB requires the semantic that two files opened at the same time
	 * with O_CREAT and O_EXCL set will return failure in at least one.
	 */
	if (arg_flags & DB_CREATE)
		flags |= O_CREAT;

	if (arg_flags & DB_EXCL)
		flags |= O_EXCL;

	if (arg_flags & DB_RDONLY)
		flags |= O_RDONLY;
	else
		flags |= O_RDWR;

#if defined(_WIN32) || defined(WIN16)
#ifdef _MSC_VER
	if (arg_flags & DB_SEQUENTIAL)
		flags |= _O_SEQUENTIAL;
	else
		flags |= _O_RANDOM;

	if (arg_flags & DB_TEMPORARY)
		flags |= _O_TEMPORARY;
#endif
	flags |= O_BINARY | O_NOINHERIT;
#endif

	if (arg_flags & DB_TRUNCATE)
		flags |= O_TRUNC;

#if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
	/*
	 * We block every signal we can get our hands on so that the temporary
	 * file isn't left around if we're interrupted at the wrong time.  Of
	 * course, if we drop core in-between the calls we'll hang forever, but
	 * that's probably okay.  ;-)
	 */
	if (arg_flags & DB_TEMPORARY) {
		(void)sigfillset(&set);
		(void)sigprocmask(SIG_BLOCK, &set, &oset);
	}
#endif

	/* Open the file. */
	if ((ret = __os_open(name, flags, mode, fdp)) != 0)
		return (ret);

#if !defined(_WIN32)
	/* Delete any temporary file; done for Win32 by _O_TEMPORARY. */
	if (arg_flags & DB_TEMPORARY) {
		(void)__os_unlink(name);
#if defined(HAVE_SIGFILLSET)
		(void)sigprocmask(SIG_SETMASK, &oset, NULL);
#endif
	}
#endif

#if !defined(_WIN32) && !defined(WIN16) && !defined(VMS)
	/*
	 * Deny access to any child process.
	 *	VMS: does not have fd inheritance.
	 *	Win32: done by O_NOINHERIT.
	 */
	if (fcntl(*fdp, F_SETFD, 1) == -1) {
		ret = errno;

		(void)__os_close(*fdp);
		return (ret);
	}
#endif
	return (0);
}

/*
 * __os_open --
 *	Open a file.
 *
 * PUBLIC: int __os_open __P((const char *, int, int, int *));
 */
int
__os_open(name, flags, mode, fdp)
	const char *name;
	int flags, mode, *fdp;
{
	*fdp = __db_jump.j_open != NULL ?
	    __db_jump.j_open(name, flags, mode) : open(name, flags, mode);
	return (*fdp == -1 ? errno : 0);
}

/*
 * __os_close --
 *	Close a file descriptor.
 *
 * PUBLIC: int __os_close __P((int));
 */
int
__os_close(fd)
	int fd;
{
	int ret;

	ret = __db_jump.j_close != NULL ? __db_jump.j_close(fd) : close(fd);
	return (ret == 0 ? 0 : errno);
}