1 /*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997, 1998
5 * Sleepycat Software. All rights reserved.
6 */
7
8 #include "config.h"
9
10 #ifndef lint
11 static const char sccsid[] = "@(#)os_open.c 10.33 (Sleepycat) 10/12/98";
12 #endif /* not lint */
13
14 #ifndef NO_SYSTEM_INCLUDES
15 #include <sys/types.h>
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <unistd.h>
21 #endif
22
23 #include "db_int.h"
24 #include "os_jump.h"
25
26 /*
27 * __db_open --
28 * Open a file descriptor.
29 *
30 * PUBLIC: int __db_open __P((const char *, u_int32_t, u_int32_t, int, int *));
31 */
32 int
__db_open(name,arg_flags,ok_flags,mode,fdp)33 __db_open(name, arg_flags, ok_flags, mode, fdp)
34 const char *name;
35 u_int32_t arg_flags, ok_flags;
36 int mode, *fdp;
37 {
38 #if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
39 sigset_t set, oset;
40 #endif
41 int flags, ret;
42
43 if (arg_flags & ~ok_flags)
44 return (EINVAL);
45
46 flags = 0;
47
48 /*
49 * DB requires the semantic that two files opened at the same time
50 * with O_CREAT and O_EXCL set will return failure in at least one.
51 */
52 if (arg_flags & DB_CREATE)
53 flags |= O_CREAT;
54
55 if (arg_flags & DB_EXCL)
56 flags |= O_EXCL;
57
58 if (arg_flags & DB_RDONLY)
59 flags |= O_RDONLY;
60 else
61 flags |= O_RDWR;
62
63 #if defined(_WIN32) || defined(WIN16)
64 #ifdef _MSC_VER
65 if (arg_flags & DB_SEQUENTIAL)
66 flags |= _O_SEQUENTIAL;
67 else
68 flags |= _O_RANDOM;
69
70 if (arg_flags & DB_TEMPORARY)
71 flags |= _O_TEMPORARY;
72 #endif
73 flags |= O_BINARY | O_NOINHERIT;
74 #endif
75
76 if (arg_flags & DB_TRUNCATE)
77 flags |= O_TRUNC;
78
79 #if !defined(_WIN32) && defined(HAVE_SIGFILLSET)
80 /*
81 * We block every signal we can get our hands on so that the temporary
82 * file isn't left around if we're interrupted at the wrong time. Of
83 * course, if we drop core in-between the calls we'll hang forever, but
84 * that's probably okay. ;-)
85 */
86 if (arg_flags & DB_TEMPORARY) {
87 (void)sigfillset(&set);
88 (void)sigprocmask(SIG_BLOCK, &set, &oset);
89 }
90 #endif
91
92 /* Open the file. */
93 if ((ret = __os_open(name, flags, mode, fdp)) != 0)
94 return (ret);
95
96 #if !defined(_WIN32)
97 /* Delete any temporary file; done for Win32 by _O_TEMPORARY. */
98 if (arg_flags & DB_TEMPORARY) {
99 (void)__os_unlink(name);
100 #if defined(HAVE_SIGFILLSET)
101 (void)sigprocmask(SIG_SETMASK, &oset, NULL);
102 #endif
103 }
104 #endif
105
106 #if !defined(_WIN32) && !defined(WIN16) && !defined(VMS)
107 /*
108 * Deny access to any child process.
109 * VMS: does not have fd inheritance.
110 * Win32: done by O_NOINHERIT.
111 */
112 if (fcntl(*fdp, F_SETFD, 1) == -1) {
113 ret = errno;
114
115 (void)__os_close(*fdp);
116 return (ret);
117 }
118 #endif
119 return (0);
120 }
121
122 /*
123 * __os_open --
124 * Open a file.
125 *
126 * PUBLIC: int __os_open __P((const char *, int, int, int *));
127 */
128 int
__os_open(name,flags,mode,fdp)129 __os_open(name, flags, mode, fdp)
130 const char *name;
131 int flags, mode, *fdp;
132 {
133 *fdp = __db_jump.j_open != NULL ?
134 __db_jump.j_open(name, flags, mode) : open(name, flags, mode);
135 return (*fdp == -1 ? errno : 0);
136 }
137
138 /*
139 * __os_close --
140 * Close a file descriptor.
141 *
142 * PUBLIC: int __os_close __P((int));
143 */
144 int
__os_close(fd)145 __os_close(fd)
146 int fd;
147 {
148 int ret;
149
150 ret = __db_jump.j_close != NULL ? __db_jump.j_close(fd) : close(fd);
151 return (ret == 0 ? 0 : errno);
152 }
153