1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1997,2008 Oracle. All rights reserved. 5 * 6 * $Id: os_getenv.c,v 1.9 2008/01/08 20:58:46 bostic Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12 13/* 14 * __os_getenv -- 15 * Retrieve an environment variable. 16 */ 17int 18__os_getenv(env, name, bpp, buflen) 19 ENV *env; 20 const char *name; 21 char **bpp; 22 size_t buflen; 23{ 24#ifdef DB_WINCE 25 COMPQUIET(name, NULL); 26 /* WinCE does not have a getenv implementation. */ 27 return (0); 28#else 29 _TCHAR *tname, tbuf[1024]; 30 int ret; 31 char *p; 32 33 /* 34 * If there's a value and the buffer is large enough: 35 * copy value into the pointer, return 0 36 * If there's a value and the buffer is too short: 37 * set pointer to NULL, return EINVAL 38 * If there's no value: 39 * set pointer to NULL, return 0 40 */ 41 if ((p = getenv(name)) != NULL) { 42 if (strlen(p) < buflen) { 43 (void)strcpy(*bpp, p); 44 return (0); 45 } 46 goto small_buf; 47 } 48 49 TO_TSTRING(env, name, tname, ret); 50 if (ret != 0) 51 return (ret); 52 /* 53 * The declared size of the tbuf buffer limits the maximum environment 54 * variable size in Berkeley DB on Windows. If that's too small, or if 55 * we need to get rid of large allocations on the BDB stack, we should 56 * malloc the tbuf memory. 57 */ 58 ret = GetEnvironmentVariable(tname, tbuf, sizeof(tbuf)); 59 FREE_STRING(env, tname); 60 61 /* 62 * If GetEnvironmentVariable succeeds, the return value is the number 63 * of characters stored in the buffer pointed to by lpBuffer, not 64 * including the terminating null character. If the buffer is not 65 * large enough to hold the data, the return value is the buffer size, 66 * in characters, required to hold the string and its terminating null 67 * character. If GetEnvironmentVariable fails, the return value is 68 * zero. If the specified environment variable was not found in the 69 * environment block, GetLastError returns ERROR_ENVVAR_NOT_FOUND. 70 */ 71 if (ret == 0) { 72 if ((ret = __os_get_syserr()) == ERROR_ENVVAR_NOT_FOUND) { 73 *bpp = NULL; 74 return (0); 75 } 76 __db_syserr(env, ret, "GetEnvironmentVariable"); 77 return (__os_posix_err(ret)); 78 } 79 if (ret > (int)sizeof(tbuf)) 80 goto small_buf; 81 82 FROM_TSTRING(env, tbuf, p, ret); 83 if (ret != 0) 84 return (ret); 85 if (strlen(p) < buflen) 86 (void)strcpy(*bpp, p); 87 else 88 *bpp = NULL; 89 FREE_STRING(env, p); 90 if (*bpp == NULL) 91 goto small_buf; 92 93 return (0); 94 95small_buf: 96 *bpp = NULL; 97 __db_errx(env, 98 "%s: buffer too small to hold environment variable %s", 99 name, p); 100 return (EINVAL); 101#endif 102} 103