summaryrefslogtreecommitdiff
path: root/src/os_windows/os_getenv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/os_windows/os_getenv.c')
-rw-r--r--src/os_windows/os_getenv.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/os_windows/os_getenv.c b/src/os_windows/os_getenv.c
new file mode 100644
index 00000000..aad59d01
--- /dev/null
+++ b/src/os_windows/os_getenv.c
@@ -0,0 +1,103 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ *
+ * $Id$
+ */
+
+#include "db_config.h"
+
+#include "db_int.h"
+
+/*
+ * __os_getenv --
+ * Retrieve an environment variable.
+ */
+int
+__os_getenv(env, name, bpp, buflen)
+ ENV *env;
+ const char *name;
+ char **bpp;
+ size_t buflen;
+{
+#ifdef DB_WINCE
+ COMPQUIET(name, NULL);
+ /* WinCE does not have a getenv implementation. */
+ return (0);
+#else
+ _TCHAR *tname, tbuf[1024];
+ int ret;
+ char *p;
+
+ /*
+ * If there's a value and the buffer is large enough:
+ * copy value into the pointer, return 0
+ * If there's a value and the buffer is too short:
+ * set pointer to NULL, return EINVAL
+ * If there's no value:
+ * set pointer to NULL, return 0
+ */
+ if ((p = getenv(name)) != NULL) {
+ if (strlen(p) < buflen) {
+ (void)strcpy(*bpp, p);
+ return (0);
+ }
+ goto small_buf;
+ }
+
+ TO_TSTRING(env, name, tname, ret);
+ if (ret != 0)
+ return (ret);
+ /*
+ * The declared size of the tbuf buffer limits the maximum environment
+ * variable size in Berkeley DB on Windows. If that's too small, or if
+ * we need to get rid of large allocations on the BDB stack, we should
+ * malloc the tbuf memory.
+ */
+ ret = GetEnvironmentVariable(tname, tbuf, sizeof(tbuf));
+ FREE_STRING(env, tname);
+
+ /*
+ * If GetEnvironmentVariable succeeds, the return value is the number
+ * of characters stored in the buffer pointed to by lpBuffer, not
+ * including the terminating null character. If the buffer is not
+ * large enough to hold the data, the return value is the buffer size,
+ * in characters, required to hold the string and its terminating null
+ * character. If GetEnvironmentVariable fails, the return value is
+ * zero. If the specified environment variable was not found in the
+ * environment block, GetLastError returns ERROR_ENVVAR_NOT_FOUND.
+ */
+ if (ret == 0) {
+ if ((ret = __os_get_syserr()) == ERROR_ENVVAR_NOT_FOUND) {
+ *bpp = NULL;
+ return (0);
+ }
+ __db_syserr(env, ret, DB_STR("0026",
+ "GetEnvironmentVariable"));
+ return (__os_posix_err(ret));
+ }
+ if (ret > (int)sizeof(tbuf))
+ goto small_buf;
+
+ FROM_TSTRING(env, tbuf, p, ret);
+ if (ret != 0)
+ return (ret);
+ if (strlen(p) < buflen)
+ (void)strcpy(*bpp, p);
+ else
+ *bpp = NULL;
+ FREE_STRING(env, p);
+ if (*bpp == NULL)
+ goto small_buf;
+
+ return (0);
+
+small_buf:
+ *bpp = NULL;
+ __db_errx(env, DB_STR_A("0027",
+ "%s: buffer too small to hold environment variable %s", "%s %s"),
+ name, p);
+ return (EINVAL);
+#endif
+}