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 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 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 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