summaryrefslogtreecommitdiff
path: root/db-4.8.30/os_windows/os_handle.c
diff options
context:
space:
mode:
authorJesse Morgan <jesse@jesterpm.net>2016-12-17 21:28:53 -0800
committerJesse Morgan <jesse@jesterpm.net>2016-12-17 21:28:53 -0800
commit54df2afaa61c6a03cbb4a33c9b90fa572b6d07b8 (patch)
tree18147b92b969d25ffbe61935fb63035cac820dd0 /db-4.8.30/os_windows/os_handle.c
Berkeley DB 4.8 with rust build script for linux.
Diffstat (limited to 'db-4.8.30/os_windows/os_handle.c')
-rw-r--r--db-4.8.30/os_windows/os_handle.c165
1 files changed, 165 insertions, 0 deletions
diff --git a/db-4.8.30/os_windows/os_handle.c b/db-4.8.30/os_windows/os_handle.c
new file mode 100644
index 0000000..74681e3
--- /dev/null
+++ b/db-4.8.30/os_windows/os_handle.c
@@ -0,0 +1,165 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1998-2009 Oracle. All rights reserved.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_openhandle --
+ * Open a file, using POSIX 1003.1 open flags.
+ */
+int
+__os_openhandle(env, name, flags, mode, fhpp)
+ ENV *env;
+ const char *name;
+ int flags, mode;
+ DB_FH **fhpp;
+{
+#ifdef DB_WINCE
+ /*
+ * __os_openhandle API is not implemented on WinCE.
+ * It is not currently called from within the Berkeley DB library,
+ * so don't log the failure via the __db_err mechanism.
+ */
+ return (EFAULT);
+#else
+ DB_FH *fhp;
+ int ret, nrepeat, retries;
+
+ /*
+ * Allocate the file handle and copy the file name. We generally only
+ * use the name for verbose or error messages, but on systems where we
+ * can't unlink temporary files immediately, we use the name to unlink
+ * the temporary file when the file handle is closed.
+ *
+ * Lock the ENV handle and insert the new file handle on the list.
+ */
+ if ((ret = __os_calloc(env, 1, sizeof(DB_FH), &fhp)) != 0)
+ return (ret);
+ if ((ret = __os_strdup(env, name, &fhp->name)) != 0)
+ goto err;
+ if (env != NULL) {
+ MUTEX_LOCK(env, env->mtx_env);
+ TAILQ_INSERT_TAIL(&env->fdlist, fhp, q);
+ MUTEX_UNLOCK(env, env->mtx_env);
+ F_SET(fhp, DB_FH_ENVLINK);
+ }
+
+ retries = 0;
+ for (nrepeat = 1; nrepeat < 4; ++nrepeat) {
+ fhp->fd = _open(name, flags, mode);
+
+ if (fhp->fd != -1) {
+ ret = 0;
+ break;
+ }
+
+ switch (ret = __os_posix_err(__os_get_syserr())) {
+ case EMFILE:
+ case ENFILE:
+ case ENOSPC:
+ /*
+ * If it's a "temporary" error, we retry up to 3 times,
+ * waiting up to 12 seconds. While it's not a problem
+ * if we can't open a database, an inability to open a
+ * log file is cause for serious dismay.
+ */
+ __os_yield(env, nrepeat * 2, 0);
+ break;
+ case EAGAIN:
+ case EBUSY:
+ case EINTR:
+ /*
+ * If an EAGAIN, EBUSY or EINTR, retry immediately for
+ * DB_RETRY times.
+ */
+ if (++retries < DB_RETRY)
+ --nrepeat;
+ break;
+ default:
+ /* Open is silent on error. */
+ goto err;
+ }
+ }
+
+ if (ret == 0) {
+ F_SET(fhp, DB_FH_OPENED);
+ *fhpp = fhp;
+ return (0);
+ }
+
+err: (void)__os_closehandle(env, fhp);
+ return (ret);
+#endif
+}
+
+/*
+ * __os_closehandle --
+ * Close a file.
+ */
+int
+__os_closehandle(env, fhp)
+ ENV *env;
+ DB_FH *fhp;
+{
+ DB_ENV *dbenv;
+ int ret, t_ret;
+
+ ret = 0;
+
+ if (env != NULL) {
+ dbenv = env->dbenv;
+ if (fhp->name != NULL && FLD_ISSET(
+ dbenv->verbose, DB_VERB_FILEOPS | DB_VERB_FILEOPS_ALL))
+ __db_msg(env, "fileops: %s: close", fhp->name);
+
+ if (F_ISSET(fhp, DB_FH_ENVLINK)) {
+ /*
+ * Lock the ENV handle and remove this file
+ * handle from the list.
+ */
+ MUTEX_LOCK(env, env->mtx_env);
+ TAILQ_REMOVE(&env->fdlist, fhp, q);
+ MUTEX_UNLOCK(env, env->mtx_env);
+ }
+ }
+
+ /* Discard any underlying system file reference. */
+ if (F_ISSET(fhp, DB_FH_OPENED)) {
+ if (fhp->handle != INVALID_HANDLE_VALUE)
+ RETRY_CHK((!CloseHandle(fhp->handle)), ret);
+ else
+#ifdef DB_WINCE
+ ret = EFAULT;
+#else
+ RETRY_CHK((_close(fhp->fd)), ret);
+#endif
+
+ if (fhp->trunc_handle != INVALID_HANDLE_VALUE) {
+ RETRY_CHK((!CloseHandle(fhp->trunc_handle)), t_ret);
+ if (t_ret != 0 && ret == 0)
+ ret = t_ret;
+ }
+
+ if (ret != 0) {
+ __db_syserr(env, ret, "CloseHandle");
+ ret = __os_posix_err(ret);
+ }
+ }
+
+ /* Unlink the file if we haven't already done so. */
+ if (F_ISSET(fhp, DB_FH_UNLINK))
+ (void)__os_unlink(env, fhp->name, 0);
+
+ if (fhp->name != NULL)
+ __os_free(env, fhp->name);
+ __os_free(env, fhp);
+
+ return (ret);
+}