xref: /titanic_50/usr/src/cmd/sendmail/db/os/os_open.c (revision c77a61a72b5ecdc507d6cf104142edd371a16c84)
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
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
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
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