/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1997, 1998, 1999 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint static const char sccsid[] = "@(#)os_open.c 11.1 (Sleepycat) 7/25/99"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES #include #include #include #endif #include "db_int.h" /* * CDB___os_open -- * Open a file. * * PUBLIC: int CDB___os_open __P((const char *, u_int32_t, int, DB_FH *)); */ int CDB___os_open(name, flags, mode, fhp) const char *name; u_int32_t flags; int mode; DB_FH *fhp; { #if defined(HAVE_SIGFILLSET) sigset_t set, oset; #endif int oflags, ret; oflags = 0; /* * DB requires the POSIX 1003.1 semantic that two files opened at the * same time with DB_OSO_CREATE/O_CREAT and DB_OSO_EXCL/O_EXCL flags * set return an EEXIST failure in at least one. */ if (LF_ISSET(DB_OSO_CREATE)) oflags |= O_CREAT; if (LF_ISSET(DB_OSO_EXCL)) oflags |= O_EXCL; #if defined(O_DSYNC) && defined(XXX_NEVER_SET) /* * !!! * We should get better performance if we push the log files to disk * immediately instead of waiting for the sync. However, Solaris * (and likely any other system based on the 4BSD filesystem releases), * doesn't implement O_DSYNC correctly, only flushing data blocks and * not inode or indirect blocks. */ if (LF_ISSET(DB_OSO_LOG)) oflags |= O_DSYNC; #endif if (LF_ISSET(DB_OSO_RDONLY)) oflags |= O_RDONLY; else oflags |= O_RDWR; if (LF_ISSET(DB_OSO_TRUNC)) oflags |= O_TRUNC; #if 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 (LF_ISSET(DB_OSO_TEMP)) { (void)sigfillset(&set); (void)sigprocmask(SIG_BLOCK, &set, &oset); } #endif /* Open the file. */ if ((ret = CDB___os_openhandle(name, oflags, mode, fhp)) != 0) return (ret); /* Delete any temporary file. */ if (LF_ISSET(DB_OSO_TEMP)) { (void)CDB___os_unlink(name); #if defined(HAVE_SIGFILLSET) (void)sigprocmask(SIG_SETMASK, &oset, NULL); #endif } #if defined(HAVE_FCNTL_F_SETFD) /* Deny file descriptor access to any child process. */ if (fcntl(fhp->fd, F_SETFD, 1) == -1) { ret = CDB___os_get_errno(); (void)CDB___os_closehandle(fhp); return (ret); } #endif return (0); }