📄 env_open.c
字号:
(a == NULL ? 0 : strlen(a) + 1) + (b == NULL ? 0 : strlen(b) + 1) + (file == NULL ? 0 : strlen(file) + 1); /* * Allocate space to hold the current path information, as well as any * temporary space that we're going to need to create a temporary file * name. */#define DB_TRAIL "BDBXXXXX" str_len = len + sizeof(DB_TRAIL) + 10; if ((ret = __os_malloc(dbenv, str_len, &str)) != 0) return (ret); slash = 0; p = str; DB_ADDSTR(a); DB_ADDSTR(b); DB_ADDSTR(file); *p = '\0'; /* * If we're opening a data file, see if it exists. If it does, * return it, otherwise, try and find another one to open. */ if (__os_exists(str, NULL) != 0 && data_entry != -1) { __os_free(dbenv, str); b = NULL; goto retry; } /* Create the file if so requested. */ if (tmp_create && (ret = __db_tmp_open(dbenv, tmp_oflags, str, fhpp)) != 0) { __os_free(dbenv, str); return (ret); } if (namep == NULL) __os_free(dbenv, str); else *namep = str; return (0);}/* * __db_home -- * Find the database home. * * PUBLIC: int __db_home __P((DB_ENV *, const char *, u_int32_t)); */int__db_home(dbenv, db_home, flags) DB_ENV *dbenv; const char *db_home; u_int32_t flags;{ const char *p; /* * Use db_home by default, this allows utilities to reasonably * override the environment either explicitly or by using a -h * option. Otherwise, use the environment if it's permitted * and initialized. */ if ((p = db_home) == NULL && (LF_ISSET(DB_USE_ENVIRON) || (LF_ISSET(DB_USE_ENVIRON_ROOT) && __os_isroot())) && (p = getenv("DB_HOME")) != NULL && p[0] == '\0') { __db_err(dbenv, "illegal DB_HOME environment variable"); return (EINVAL); } return (p == NULL ? 0 : __os_strdup(dbenv, p, &dbenv->db_home));}#define __DB_OVFL(v, max) \ if (v > max) { \ __v = v; \ __max = max; \ goto toobig; \ }/* * __db_parse -- * Parse a single NAME VALUE pair. */static int__db_parse(dbenv, s) DB_ENV *dbenv; char *s;{ u_long __max, __v, v1, v2, v3; u_int32_t flags; char *name, *p, *value, v4; /* * !!! * The constant 40 is hard-coded into format arguments to sscanf * below, it can't be changed here without changing it there, too. * The additional bytes are for a trailing nul byte and because we * are reading user input -- I don't want to risk any off-by-ones. */ char arg[40 + 5]; /* * Name/value pairs are parsed as two white-space separated strings. * Leading and trailing white-space is trimmed from the value, but * it may contain embedded white-space. Note: we use the isspace(3) * macro because it's more portable, but that means that you can use * characters like form-feed to separate the strings. */ name = s; for (p = name; *p != '\0' && !isspace((int)*p); ++p) ; if (*p == '\0' || p == name) goto illegal; *p = '\0'; for (++p; isspace((int)*p); ++p) ; if (*p == '\0') goto illegal; value = p; for (++p; *p != '\0'; ++p) ; for (--p; isspace((int)*p); --p) ; ++p; if (p == value) {illegal: __db_err(dbenv, "mis-formatted name-value pair: %s", s); return (EINVAL); } *p = '\0'; if (!strcasecmp(name, "set_cachesize")) { if (sscanf(value, "%lu %lu %lu %c", &v1, &v2, &v3, &v4) != 3) goto badarg; __DB_OVFL(v1, UINT32_MAX); __DB_OVFL(v2, UINT32_MAX); __DB_OVFL(v3, 10000); return (__memp_set_cachesize( dbenv, (u_int32_t)v1, (u_int32_t)v2, (int)v3)); } if (!strcasecmp(name, "set_data_dir") || !strcasecmp(name, "db_data_dir")) /* Compatibility. */ return (__dbenv_set_data_dir(dbenv, value)); if (!strcasecmp(name, "set_intermediate_dir")) {/* Undocumented. */ if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg;#ifdef INT_MAX __DB_OVFL(v1, INT_MAX);#endif return (__dbenv_set_intermediate_dir(dbenv, (int)v1, 0)); } if (!strcasecmp(name, "set_flags")) { if (sscanf(value, "%40s %c", arg, &v4) != 1) goto badarg; if (!strcasecmp(value, "db_auto_commit")) return (__dbenv_set_flags(dbenv, DB_AUTO_COMMIT, 1)); if (!strcasecmp(value, "db_cdb_alldb")) return (__dbenv_set_flags(dbenv, DB_CDB_ALLDB, 1)); if (!strcasecmp(value, "db_direct_db")) return (__dbenv_set_flags(dbenv, DB_DIRECT_DB, 1)); if (!strcasecmp(value, "db_direct_log")) return (__dbenv_set_flags(dbenv, DB_DIRECT_LOG, 1)); if (!strcasecmp(value, "db_dsync_log")) return (__dbenv_set_flags(dbenv, DB_DSYNC_LOG, 1)); if (!strcasecmp(value, "db_log_autoremove")) return (__dbenv_set_flags(dbenv, DB_LOG_AUTOREMOVE, 1)); if (!strcasecmp(value, "db_log_inmemory")) return (__dbenv_set_flags(dbenv, DB_LOG_INMEMORY, 1)); if (!strcasecmp(value, "db_nolocking")) return (__dbenv_set_flags(dbenv, DB_NOLOCKING, 1)); if (!strcasecmp(value, "db_nommap")) return (__dbenv_set_flags(dbenv, DB_NOMMAP, 1)); if (!strcasecmp(value, "db_nopanic")) return (__dbenv_set_flags(dbenv, DB_NOPANIC, 1)); if (!strcasecmp(value, "db_overwrite")) return (__dbenv_set_flags(dbenv, DB_OVERWRITE, 1)); if (!strcasecmp(value, "db_region_init")) return (__dbenv_set_flags(dbenv, DB_REGION_INIT, 1)); if (!strcasecmp(value, "db_txn_nosync")) return (__dbenv_set_flags(dbenv, DB_TXN_NOSYNC, 1)); if (!strcasecmp(value, "db_txn_write_nosync")) return ( __dbenv_set_flags(dbenv, DB_TXN_WRITE_NOSYNC, 1)); if (!strcasecmp(value, "db_yieldcpu")) return (__dbenv_set_flags(dbenv, DB_YIELDCPU, 1)); goto badarg; } if (!strcasecmp(name, "set_lg_bsize")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__log_set_lg_bsize(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_lg_max")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__log_set_lg_max(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_lg_regionmax")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__log_set_lg_regionmax(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_lg_dir") || !strcasecmp(name, "db_log_dir")) /* Compatibility. */ return (__log_set_lg_dir(dbenv, value)); if (!strcasecmp(name, "set_lk_detect")) { if (sscanf(value, "%40s %c", arg, &v4) != 1) goto badarg; if (!strcasecmp(value, "db_lock_default")) flags = DB_LOCK_DEFAULT; else if (!strcasecmp(value, "db_lock_expire")) flags = DB_LOCK_EXPIRE; else if (!strcasecmp(value, "db_lock_maxlocks")) flags = DB_LOCK_MAXLOCKS; else if (!strcasecmp(value, "db_lock_maxwrite")) flags = DB_LOCK_MAXWRITE; else if (!strcasecmp(value, "db_lock_minlocks")) flags = DB_LOCK_MINLOCKS; else if (!strcasecmp(value, "db_lock_minwrite")) flags = DB_LOCK_MINWRITE; else if (!strcasecmp(value, "db_lock_oldest")) flags = DB_LOCK_OLDEST; else if (!strcasecmp(value, "db_lock_random")) flags = DB_LOCK_RANDOM; else if (!strcasecmp(value, "db_lock_youngest")) flags = DB_LOCK_YOUNGEST; else goto badarg; return (__lock_set_lk_detect(dbenv, flags)); } if (!strcasecmp(name, "set_lk_max")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__lock_set_lk_max(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_lk_max_locks")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__lock_set_lk_max_locks(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_lk_max_lockers")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__lock_set_lk_max_lockers(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_lk_max_objects")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__lock_set_lk_max_objects(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_lock_timeout")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__lock_set_env_timeout( dbenv, (u_int32_t)v1, DB_SET_LOCK_TIMEOUT)); } if (!strcasecmp(name, "set_mp_max_openfd")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, INT_MAX); return (__memp_set_mp_max_openfd(dbenv, (int)v1)); } if (!strcasecmp(name, "set_mp_max_write")) { if (sscanf(value, "%lu %lu %c", &v1, &v2, &v4) != 2) goto badarg; __DB_OVFL(v1, INT_MAX); __DB_OVFL(v2, INT_MAX); return (__memp_set_mp_max_write(dbenv, (int)v1, (int)v2)); } if (!strcasecmp(name, "set_mp_mmapsize")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__memp_set_mp_mmapsize(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_region_init")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1 || v1 != 1) goto badarg; return (__dbenv_set_flags( dbenv, DB_REGION_INIT, v1 == 0 ? 0 : 1)); } if (!strcasecmp(name, "set_shm_key")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; return (__dbenv_set_shm_key(dbenv, (long)v1)); } if (!strcasecmp(name, "set_tas_spins")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__dbenv_set_tas_spins(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_tmp_dir") || !strcasecmp(name, "db_tmp_dir")) /* Compatibility.*/ return (__dbenv_set_tmp_dir(dbenv, value)); if (!strcasecmp(name, "set_tx_max")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__txn_set_tx_max(dbenv, (u_int32_t)v1)); } if (!strcasecmp(name, "set_txn_timeout")) { if (sscanf(value, "%lu %c", &v1, &v4) != 1) goto badarg; __DB_OVFL(v1, UINT32_MAX); return (__lock_set_env_timeout( dbenv, (u_int32_t)v1, DB_SET_TXN_TIMEOUT)); } if (!strcasecmp(name, "set_verbose")) { if (sscanf(value, "%40s %c", arg, &v4) != 1) goto badarg; else if (!strcasecmp(value, "db_verb_deadlock")) flags = DB_VERB_DEADLOCK; else if (!strcasecmp(value, "db_verb_recovery")) flags = DB_VERB_RECOVERY; else if (!strcasecmp(value, "db_verb_replication")) flags = DB_VERB_REPLICATION; else if (!strcasecmp(value, "db_verb_waitsfor")) flags = DB_VERB_WAITSFOR; else goto badarg; return (__dbenv_set_verbose(dbenv, flags, 1)); } __db_err(dbenv, "unrecognized name-value pair: %s", s); return (EINVAL);badarg: __db_err(dbenv, "incorrect arguments for name-value pair: %s", s); return (EINVAL);toobig: __db_err(dbenv, "%s: %lu larger than maximum value %lu", s, __v, __max); return (EINVAL);}/* * __db_tmp_open -- * Create a temporary file. */static int__db_tmp_open(dbenv, tmp_oflags, path, fhpp) DB_ENV *dbenv; u_int32_t tmp_oflags; char *path; DB_FH **fhpp;{ u_int32_t id; int filenum, i, isdir, ret; char *firstx, *trv; /* * Check the target directory; if you have six X's and it doesn't * exist, this runs for a *very* long time. */ if ((ret = __os_exists(path, &isdir)) != 0) { __db_err(dbenv, "%s: %s", path, db_strerror(ret)); return (ret); } if (!isdir) { __db_err(dbenv, "%s: %s", path, db_strerror(EINVAL)); return (EINVAL); } /* Build the path. */ (void)strncat(path, PATH_SEPARATOR, 1); (void)strcat(path, DB_TRAIL); /* Replace the X's with the process ID (in decimal). */ for (trv = path + strlen(path), __os_id(&id); *--trv == 'X'; id /= 10) *trv = '0' + (id % 10); firstx = trv + 1; /* Loop, trying to open a file. */ for (filenum = 1;; filenum++) { if ((ret = __os_open(dbenv, path, tmp_oflags | DB_OSO_CREATE | DB_OSO_EXCL | DB_OSO_TEMP, __db_omode("rw----"), fhpp)) == 0) return (0); /* * !!!: * If we don't get an EEXIST error, then there's something * seriously wrong. Unfortunately, if the implementation * doesn't return EEXIST for O_CREAT and O_EXCL regardless * of other possible errors, we've lost. */ if (ret != EEXIST) { __db_err(dbenv, "tmp_open: %s: %s", path, db_strerror(ret)); return (ret); } /* * Generate temporary file names in a backwards-compatible way. * If id == 12345, the result is: * <path>/DB12345 (tried above, the first time through). * <path>/DBa2345 ... <path>/DBz2345 * <path>/DBaa345 ... <path>/DBaz345 * <path>/DBba345, and so on. * * XXX * This algorithm is O(n**2) -- that is, creating 100 temporary * files requires 5,000 opens, creating 1000 files requires * 500,000. If applications open a lot of temporary files, we * could improve performance by switching to timestamp-based * file names. */ for (i = filenum, trv = firstx; i > 0; i = (i - 1) / 26) if (*trv++ == '\0') return (EINVAL); for (i = filenum; i > 0; i = (i - 1) / 26) *--trv = 'a' + ((i - 1) % 26); } /* NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -