Module Name: src
Committed By: christos
Date: Sun Dec 1 00:22:48 UTC 2013
Modified Files:
src/lib/libc/db/btree: bt_open.c bt_overflow.c bt_utils.c
src/lib/libc/db/db: Makefile.inc
src/lib/libc/db/hash: hash.c hash_page.c
src/lib/libc/db/recno: rec_open.c rec_put.c rec_utils.c
Added Files:
src/lib/libc/db/db: dbfile.c
Log Message:
- centralize opening of regular and temp files to avoid code duplication
- don't cast malloc
- use malloc sizeof(*var) instead of sizeof(type)
To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/lib/libc/db/btree/bt_open.c
cvs rdiff -u -r1.18 -r1.19 src/lib/libc/db/btree/bt_overflow.c
cvs rdiff -u -r1.14 -r1.15 src/lib/libc/db/btree/bt_utils.c
cvs rdiff -u -r1.4 -r1.5 src/lib/libc/db/db/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/lib/libc/db/db/dbfile.c
cvs rdiff -u -r1.32 -r1.33 src/lib/libc/db/hash/hash.c
cvs rdiff -u -r1.25 -r1.26 src/lib/libc/db/hash/hash_page.c
cvs rdiff -u -r1.19 -r1.20 src/lib/libc/db/recno/rec_open.c \
src/lib/libc/db/recno/rec_put.c
cvs rdiff -u -r1.12 -r1.13 src/lib/libc/db/recno/rec_utils.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/db/btree/bt_open.c
diff -u src/lib/libc/db/btree/bt_open.c:1.26 src/lib/libc/db/btree/bt_open.c:1.27
--- src/lib/libc/db/btree/bt_open.c:1.26 Tue Mar 13 17:13:32 2012
+++ src/lib/libc/db/btree/bt_open.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: bt_open.c,v 1.26 2012/03/13 21:13:32 christos Exp $ */
+/* $NetBSD: bt_open.c,v 1.27 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: bt_open.c,v 1.26 2012/03/13 21:13:32 christos Exp $");
+__RCSID("$NetBSD: bt_open.c,v 1.27 2013/12/01 00:22:48 christos Exp $");
/*
* Implementation of btree access method for 4.4BSD.
@@ -71,7 +71,6 @@ __RCSID("$NetBSD: bt_open.c,v 1.26 2012/
static int byteorder(void);
static int nroot(BTREE *);
-static int tmp(void);
/*
* __BT_OPEN -- Open a btree.
@@ -161,7 +160,7 @@ __bt_open(const char *fname, int flags,
goto einval;
/* Allocate and initialize DB and BTREE structures. */
- if ((t = (BTREE *)malloc(sizeof(BTREE))) == NULL)
+ if ((t = malloc(sizeof(*t))) == NULL)
goto err;
memset(t, 0, sizeof(BTREE));
t->bt_fd = -1; /* Don't close unopened fd on error. */
@@ -171,7 +170,7 @@ __bt_open(const char *fname, int flags,
t->bt_pfx = b.prefix;
t->bt_rfd = -1;
- if ((t->bt_dbp = dbp = (DB *)malloc(sizeof(DB))) == NULL)
+ if ((t->bt_dbp = dbp = malloc(sizeof(*dbp))) == NULL)
goto err;
memset(t->bt_dbp, 0, sizeof(DB));
if (t->bt_lorder != machine_lorder)
@@ -202,24 +201,17 @@ __bt_open(const char *fname, int flags,
default:
goto einval;
}
-
- if ((t->bt_fd = open(fname, flags, mode)) == -1)
- goto err;
- if (fcntl(t->bt_fd, F_SETFD, FD_CLOEXEC) == -1)
+ if ((t->bt_fd = __dbopen(fname, flags, mode, &sb)) == -1)
goto err;
} else {
if ((flags & O_ACCMODE) != O_RDWR)
goto einval;
- if ((t->bt_fd = tmp()) == -1)
+ if ((t->bt_fd = __dbtemp("bt.", &sb)) == -1)
goto err;
F_SET(t, B_INMEM);
}
- if (fcntl(t->bt_fd, F_SETFD, FD_CLOEXEC) == -1)
- goto err;
- if (fstat(t->bt_fd, &sb))
- goto err;
if (sb.st_size) {
if ((nr = read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
goto err;
@@ -390,37 +382,6 @@ nroot(BTREE *t)
}
static int
-tmp(void)
-{
- sigset_t set, oset;
- int len;
- int fd;
- char *envtmp;
- char path[PATH_MAX];
-
- if (issetugid())
- envtmp = NULL;
- else
- envtmp = getenv("TMPDIR");
-
- len = snprintf(path,
- sizeof(path), "%s/bt.XXXXXX", envtmp ? envtmp : _PATH_TMP);
- if (len < 0 || (size_t)len >= sizeof(path)) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((fd = mkstemp(path)) != -1) {
- (void)unlink(path);
- (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
- }
- (void)sigprocmask(SIG_SETMASK, &oset, NULL);
- return(fd);
-}
-
-static int
byteorder(void)
{
uint32_t x;
Index: src/lib/libc/db/btree/bt_overflow.c
diff -u src/lib/libc/db/btree/bt_overflow.c:1.18 src/lib/libc/db/btree/bt_overflow.c:1.19
--- src/lib/libc/db/btree/bt_overflow.c:1.18 Tue Mar 13 17:13:32 2012
+++ src/lib/libc/db/btree/bt_overflow.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: bt_overflow.c,v 1.18 2012/03/13 21:13:32 christos Exp $ */
+/* $NetBSD: bt_overflow.c,v 1.19 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: bt_overflow.c,v 1.18 2012/03/13 21:13:32 christos Exp $");
+__RCSID("$NetBSD: bt_overflow.c,v 1.19 2013/12/01 00:22:48 christos Exp $");
#include "namespace.h"
#include <sys/param.h>
@@ -97,7 +97,7 @@ __ovfl_get(BTREE *t, void *p, size_t *ss
#endif
/* Make the buffer bigger as necessary. */
if (*bufsz < sz) {
- *buf = (*buf == NULL ? malloc(sz) : realloc(*buf, sz));
+ *buf = *buf == NULL ? malloc(sz) : realloc(*buf, sz);
if (*buf == NULL)
return (RET_ERROR);
*bufsz = sz;
Index: src/lib/libc/db/btree/bt_utils.c
diff -u src/lib/libc/db/btree/bt_utils.c:1.14 src/lib/libc/db/btree/bt_utils.c:1.15
--- src/lib/libc/db/btree/bt_utils.c:1.14 Wed Sep 4 09:03:22 2013
+++ src/lib/libc/db/btree/bt_utils.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: bt_utils.c,v 1.14 2013/09/04 13:03:22 ryoon Exp $ */
+/* $NetBSD: bt_utils.c,v 1.15 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: bt_utils.c,v 1.14 2013/09/04 13:03:22 ryoon Exp $");
+__RCSID("$NetBSD: bt_utils.c,v 1.15 2013/12/01 00:22:48 christos Exp $");
#include <sys/param.h>
@@ -88,8 +88,8 @@ __bt_ret(BTREE *t, EPG *e, DBT *key, DBT
key->data = rkey->data;
} else if (copy || F_ISSET(t, B_DB_LOCK)) {
if (bl->ksize > rkey->size) {
- p = (void *)(rkey->data == NULL ?
- malloc(bl->ksize) : realloc(rkey->data, bl->ksize));
+ p = rkey->data == NULL ?
+ malloc(bl->ksize) : realloc(rkey->data, bl->ksize);
if (p == NULL)
return (RET_ERROR);
rkey->data = p;
@@ -115,9 +115,9 @@ dataonly:
} else if (copy || F_ISSET(t, B_DB_LOCK)) {
/* Use +1 in case the first record retrieved is 0 length. */
if (bl->dsize + 1 > rdata->size) {
- p = (void *)(rdata->data == NULL ?
+ p = rdata->data == NULL ?
malloc(bl->dsize + 1) :
- realloc(rdata->data, bl->dsize + 1));
+ realloc(rdata->data, bl->dsize + 1);
if (p == NULL)
return (RET_ERROR);
rdata->data = p;
Index: src/lib/libc/db/db/Makefile.inc
diff -u src/lib/libc/db/db/Makefile.inc:1.4 src/lib/libc/db/db/Makefile.inc:1.5
--- src/lib/libc/db/db/Makefile.inc:1.4 Mon Feb 27 08:21:22 1995
+++ src/lib/libc/db/db/Makefile.inc Sat Nov 30 19:22:48 2013
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile.inc,v 1.4 1995/02/27 13:21:22 cgd Exp $
+# $NetBSD: Makefile.inc,v 1.5 2013/12/01 00:22:48 christos Exp $
# @(#)Makefile.inc 8.1 (Berkeley) 6/4/93
.PATH: ${.CURDIR}/db/db
-SRCS+= db.c
+SRCS+= db.c dbfile.c
Index: src/lib/libc/db/hash/hash.c
diff -u src/lib/libc/db/hash/hash.c:1.32 src/lib/libc/db/hash/hash.c:1.33
--- src/lib/libc/db/hash/hash.c:1.32 Tue Mar 13 17:13:32 2012
+++ src/lib/libc/db/hash/hash.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: hash.c,v 1.32 2012/03/13 21:13:32 christos Exp $ */
+/* $NetBSD: hash.c,v 1.33 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: hash.c,v 1.32 2012/03/13 21:13:32 christos Exp $");
+__RCSID("$NetBSD: hash.c,v 1.33 2013/12/01 00:22:48 christos Exp $");
#include "namespace.h"
#include <sys/param.h>
@@ -128,12 +128,8 @@ __hash_open(const char *file, int flags,
new_table = 1;
}
if (file) {
- if ((hashp->fp = open(file, flags, mode)) == -1)
+ if ((hashp->fp = __dbopen(file, flags, mode, &statbuf)) == -1)
RETURN_ERROR(errno, error0);
- if (fcntl(hashp->fp, F_SETFD, FD_CLOEXEC) == -1)
- RETURN_ERROR(errno, error1);
- if (fstat(hashp->fp, &statbuf) == -1)
- RETURN_ERROR(errno, error1);
new_table |= statbuf.st_size == 0;
}
if (new_table) {
@@ -196,7 +192,7 @@ __hash_open(const char *file, int flags,
hashp->new_file = new_table;
hashp->save_file = file && (hashp->flags & O_RDWR);
hashp->cbucket = -1;
- if (!(dbp = malloc(sizeof(DB)))) {
+ if (!(dbp = malloc(sizeof(*dbp)))) {
save_errno = errno;
hdestroy(hashp);
errno = save_errno;
Index: src/lib/libc/db/hash/hash_page.c
diff -u src/lib/libc/db/hash/hash_page.c:1.25 src/lib/libc/db/hash/hash_page.c:1.26
--- src/lib/libc/db/hash/hash_page.c:1.25 Tue Mar 13 17:13:33 2012
+++ src/lib/libc/db/hash/hash_page.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: hash_page.c,v 1.25 2012/03/13 21:13:33 christos Exp $ */
+/* $NetBSD: hash_page.c,v 1.26 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: hash_page.c,v 1.25 2012/03/13 21:13:33 christos Exp $");
+__RCSID("$NetBSD: hash_page.c,v 1.26 2013/12/01 00:22:48 christos Exp $");
/*
* PACKAGE: hashing
@@ -52,7 +52,6 @@ __RCSID("$NetBSD: hash_page.c,v 1.25 201
* __add_ovflpage
* Internal
* overflow_page
- * open_temp
*/
#include "namespace.h"
@@ -76,7 +75,6 @@ __RCSID("$NetBSD: hash_page.c,v 1.25 201
static uint32_t *fetch_bitmap(HTAB *, int);
static uint32_t first_free(uint32_t);
-static int open_temp(HTAB *);
static uint16_t overflow_page(HTAB *);
static void putpair(char *, const DBT *, const DBT *);
static void squeeze_key(uint16_t *, const DBT *, const DBT *);
@@ -597,7 +595,7 @@ __put_page(HTAB *hashp, char *p, uint32_
ssize_t wsize;
size = hashp->BSIZE;
- if ((hashp->fp == -1) && open_temp(hashp))
+ if ((hashp->fp == -1) && (hashp->fp = __dbtemp("_hash", NULL)) == -1)
return (-1);
fd = hashp->fp;
@@ -859,42 +857,6 @@ __free_ovflpage(HTAB *hashp, BUFHEAD *ob
}
/*
- * Returns:
- * 0 success
- * -1 failure
- */
-static int
-open_temp(HTAB *hashp)
-{
- sigset_t set, oset;
- char *envtmp;
- char namestr[PATH_MAX];
- int len;
-
- if (issetugid())
- envtmp = NULL;
- else
- envtmp = getenv("TMPDIR");
-
- len = snprintf(namestr, sizeof(namestr), "%s/_hashXXXXXX",
- envtmp ? envtmp : _PATH_TMP);
- if (len < 0 || (size_t)len >= sizeof(namestr)) {
- errno = ENAMETOOLONG;
- return -1;
- }
-
- /* Block signals; make sure file goes away at process exit. */
- (void)sigfillset(&set);
- (void)sigprocmask(SIG_BLOCK, &set, &oset);
- if ((hashp->fp = mkstemp(namestr)) != -1) {
- (void)unlink(namestr);
- (void)fcntl(hashp->fp, F_SETFD, FD_CLOEXEC);
- }
- (void)sigprocmask(SIG_SETMASK, &oset, (sigset_t *)NULL);
- return (hashp->fp != -1 ? 0 : -1);
-}
-
-/*
* We have to know that the key will fit, but the last entry on the page is
* an overflow pair, so we need to shift things.
*/
Index: src/lib/libc/db/recno/rec_open.c
diff -u src/lib/libc/db/recno/rec_open.c:1.19 src/lib/libc/db/recno/rec_open.c:1.20
--- src/lib/libc/db/recno/rec_open.c:1.19 Sun Jun 26 18:27:14 2011
+++ src/lib/libc/db/recno/rec_open.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: rec_open.c,v 1.19 2011/06/26 22:27:14 christos Exp $ */
+/* $NetBSD: rec_open.c,v 1.20 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: rec_open.c,v 1.19 2011/06/26 22:27:14 christos Exp $");
+__RCSID("$NetBSD: rec_open.c,v 1.20 2013/12/01 00:22:48 christos Exp $");
#include "namespace.h"
#include <sys/types.h>
@@ -70,15 +70,8 @@ __rec_open(const char *fname, int flags,
dbp = NULL;
/* Open the user's file -- if this fails, we're done. */
if (fname != NULL) {
-#ifndef O_CLOEXEC
-#define O_CLOEXEC 0
-#endif
- if ((rfd = open(fname, flags | O_CLOEXEC, mode)) == -1)
+ if ((rfd = __dbopen(fname, flags, mode, NULL)) == -1)
return NULL;
-#if O_CLOEXEC == 0
- if (fcntl(rfd, F_SETFD, FD_CLOEXEC) == -1)
- goto err;
-#endif
}
/* Create a btree in memory (backed by disk). */
Index: src/lib/libc/db/recno/rec_put.c
diff -u src/lib/libc/db/recno/rec_put.c:1.19 src/lib/libc/db/recno/rec_put.c:1.20
--- src/lib/libc/db/recno/rec_put.c:1.19 Sun Jun 26 18:18:16 2011
+++ src/lib/libc/db/recno/rec_put.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: rec_put.c,v 1.19 2011/06/26 22:18:16 christos Exp $ */
+/* $NetBSD: rec_put.c,v 1.20 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -34,7 +34,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: rec_put.c,v 1.19 2011/06/26 22:18:16 christos Exp $");
+__RCSID("$NetBSD: rec_put.c,v 1.20 2013/12/01 00:22:48 christos Exp $");
#include "namespace.h"
#include <sys/types.h>
@@ -146,8 +146,7 @@ einval: errno = EINVAL;
return (RET_ERROR);
if (nrec > t->bt_nrecs + 1) {
if (F_ISSET(t, R_FIXLEN)) {
- if ((tdata.data =
- (void *)malloc(t->bt_reclen)) == NULL)
+ if ((tdata.data = malloc(t->bt_reclen)) == NULL)
return (RET_ERROR);
tdata.size = t->bt_reclen;
memset(tdata.data, t->bt_bval, tdata.size);
Index: src/lib/libc/db/recno/rec_utils.c
diff -u src/lib/libc/db/recno/rec_utils.c:1.12 src/lib/libc/db/recno/rec_utils.c:1.13
--- src/lib/libc/db/recno/rec_utils.c:1.12 Wed Sep 10 13:52:36 2008
+++ src/lib/libc/db/recno/rec_utils.c Sat Nov 30 19:22:48 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: rec_utils.c,v 1.12 2008/09/10 17:52:36 joerg Exp $ */
+/* $NetBSD: rec_utils.c,v 1.13 2013/12/01 00:22:48 christos Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@@ -34,7 +34,7 @@
#endif
#include <sys/cdefs.h>
-__RCSID("$NetBSD: rec_utils.c,v 1.12 2008/09/10 17:52:36 joerg Exp $");
+__RCSID("$NetBSD: rec_utils.c,v 1.13 2013/12/01 00:22:48 christos Exp $");
#include <sys/param.h>
@@ -70,17 +70,17 @@ __rec_ret(BTREE *t, EPG *e, recno_t nrec
goto dataonly;
/* We have to copy the key, it's not on the page. */
- if (sizeof(recno_t) > t->bt_rkey.size) {
- p = (void *)(t->bt_rkey.data == NULL ?
- malloc(sizeof(recno_t)) :
- realloc(t->bt_rkey.data, sizeof(recno_t)));
+ if (sizeof(nrec) > t->bt_rkey.size) {
+ p = t->bt_rkey.data == NULL ?
+ malloc(sizeof(nrec)) :
+ realloc(t->bt_rkey.data, sizeof(nrec));
if (p == NULL)
return (RET_ERROR);
t->bt_rkey.data = p;
- t->bt_rkey.size = sizeof(recno_t);
+ t->bt_rkey.size = sizeof(nrec);
}
- memmove(t->bt_rkey.data, &nrec, sizeof(recno_t));
- key->size = sizeof(recno_t);
+ memmove(t->bt_rkey.data, &nrec, sizeof(nrec));
+ key->size = sizeof(nrec);
key->data = t->bt_rkey.data;
dataonly:
@@ -101,9 +101,9 @@ dataonly:
} else if (F_ISSET(t, B_DB_LOCK)) {
/* Use +1 in case the first record retrieved is 0 length. */
if (rl->dsize + 1 > t->bt_rdata.size) {
- p = (void *)(t->bt_rdata.data == NULL ?
+ p = t->bt_rdata.data == NULL ?
malloc(rl->dsize + 1) :
- realloc(t->bt_rdata.data, rl->dsize + 1));
+ realloc(t->bt_rdata.data, rl->dsize + 1);
if (p == NULL)
return (RET_ERROR);
t->bt_rdata.data = p;
Added files:
Index: src/lib/libc/db/db/dbfile.c
diff -u /dev/null src/lib/libc/db/db/dbfile.c:1.1
--- /dev/null Sat Nov 30 19:22:49 2013
+++ src/lib/libc/db/db/dbfile.c Sat Nov 30 19:22:48 2013
@@ -0,0 +1,118 @@
+/* $NetBSD: dbfile.c,v 1.1 2013/12/01 00:22:48 christos Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if HAVE_NBTOOL_CONFIG_H
+#include "nbtool_config.h"
+#endif
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: dbfile.c,v 1.1 2013/12/01 00:22:48 christos Exp $");
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <paths.h>
+#include <db.h>
+
+int
+__dbopen(const char *file, int flags, mode_t mode, struct stat *sb)
+{
+ int fd;
+ int serrno;
+
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+
+ if ((fd = open(file, flags | O_CLOEXEC, mode)) == -1)
+ return -1;
+
+#if O_CLOEXEC == 0
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+ goto out;
+#endif
+
+ if (sb && fstat(fd, sb) == -1)
+ goto out;
+
+ return fd;
+out:
+ serrno = errno;
+ close(fd);
+ errno = serrno;
+ return -1;
+
+}
+
+int
+__dbtemp(const char *prefix, struct stat *sb)
+{
+ sigset_t set, oset;
+ int len;
+ int fd, serrno;
+ char *envtmp;
+ char path[PATH_MAX];
+
+ if (issetugid())
+ envtmp = NULL;
+ else
+ envtmp = getenv("TMPDIR");
+
+ len = snprintf(path, sizeof(path), "%s/%sXXXXXX",
+ envtmp ? envtmp : _PATH_TMP, prefix);
+ if ((size_t)len >= sizeof(path)) {
+ errno = ENAMETOOLONG;
+ return -1;
+ }
+
+ (void)sigfillset(&set);
+ (void)sigprocmask(SIG_BLOCK, &set, &oset);
+
+ if ((fd = mkstemp(path)) != -1) {
+ if (unlink(path) == -1)
+ goto out;
+
+ if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
+ goto out;
+
+ if (sb && fstat(fd, sb) == -1)
+ goto out;
+ }
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ return fd;
+out:
+ serrno = errno;
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+ close(fd);
+ errno = serrno;
+ return -1;
+}