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