141 lines
4.7 KiB
C
141 lines
4.7 KiB
C
/****************************************************************
|
|
* *
|
|
* Copyright 2001, 2013 Fidelity Information Services, Inc *
|
|
* *
|
|
* This source code contains the intellectual property *
|
|
* of its copyright holder(s), and is made available *
|
|
* under a license. If you do not know the terms of *
|
|
* the license, please stop and do not read further. *
|
|
* *
|
|
****************************************************************/
|
|
|
|
#include "mdef.h"
|
|
|
|
#include <errno.h>
|
|
#include "gtm_string.h"
|
|
#include "gdsroot.h"
|
|
#include "gdskill.h"
|
|
#include "gtm_facility.h"
|
|
#include "fileinfo.h"
|
|
#include "gdsbt.h"
|
|
#include "collseq.h"
|
|
#include "gdsfhead.h"
|
|
#include "gdscc.h"
|
|
#include "copy.h"
|
|
#include "filestruct.h"
|
|
#include "jnl.h"
|
|
#include "buddy_list.h" /* needed for tp.h */
|
|
#include "hashtab_mname.h"
|
|
#include "hashtab_int4.h" /* needed for tp.h */
|
|
#include "tp.h"
|
|
#include "change_reg.h"
|
|
#include "targ_alloc.h"
|
|
#include "gvcst_protos.h" /* for gvcst_root_search prototype */
|
|
#include "min_max.h"
|
|
|
|
GBLREF gv_namehead *gv_target;
|
|
GBLREF gv_key *gv_currkey;
|
|
GBLREF gd_region *gv_cur_region;
|
|
GBLREF gd_binding *gd_map, *gd_map_top;
|
|
|
|
error_def(ERR_KEY2BIG);
|
|
error_def(ERR_GVIS);
|
|
|
|
void gv_bind_name(gd_addr *addr, mstr *targ)
|
|
{
|
|
gd_binding *map;
|
|
ht_ent_mname *tabent;
|
|
mname_entry gvent;
|
|
int res;
|
|
boolean_t added;
|
|
enum db_acc_method acc_meth;
|
|
gd_region *reg;
|
|
gvnh_reg_t *gvnh_reg;
|
|
int keylen;
|
|
char format_key[MAX_MIDENT_LEN + 1]; /* max key length + 1 byte for '^' */
|
|
gv_namehead *tmp_gvt;
|
|
sgmnt_addrs *csa;
|
|
|
|
gd_map = addr->maps;
|
|
gd_map_top = gd_map + addr->n_maps;
|
|
gvent.var_name.addr = targ->addr;
|
|
gvent.var_name.len = MIN(targ->len, MAX_MIDENT_LEN);
|
|
COMPUTE_HASH_MNAME(&gvent);
|
|
if ((NULL != (tabent = lookup_hashtab_mname((hash_table_mname *)addr->tab_ptr, &gvent)))
|
|
&& (NULL != (gvnh_reg = (gvnh_reg_t *)tabent->value)))
|
|
{
|
|
reg = gvnh_reg->gd_reg;
|
|
if (!reg->open)
|
|
{
|
|
gv_init_reg(reg); /* could modify gvnh_reg->gvt if multiple regions map to same db file */
|
|
assert(0 == gvnh_reg->gvt->clue.end);
|
|
}
|
|
gv_target = gvnh_reg->gvt;
|
|
gv_cur_region = reg;
|
|
acc_meth = gv_cur_region->dyn.addr->acc_meth;
|
|
} else
|
|
{
|
|
map = gd_map + 1; /* get past local locks */
|
|
for (; (res = memcmp(gvent.var_name.addr, &(map->name[0]), gvent.var_name.len)) >= 0; map++)
|
|
{
|
|
assert(map < gd_map_top);
|
|
if (0 == res && 0 != map->name[gvent.var_name.len])
|
|
break;
|
|
}
|
|
if (!map->reg.addr->open)
|
|
gv_init_reg(map->reg.addr);
|
|
gv_cur_region = map->reg.addr;
|
|
acc_meth = gv_cur_region->dyn.addr->acc_meth;
|
|
if ((dba_cm == acc_meth) || (dba_usr == acc_meth))
|
|
{
|
|
tmp_gvt = malloc(SIZEOF(gv_namehead) + gvent.var_name.len);
|
|
memset(tmp_gvt, 0, SIZEOF(gv_namehead) + gvent.var_name.len);
|
|
tmp_gvt->gvname.var_name.addr = (char *)tmp_gvt + SIZEOF(gv_namehead);
|
|
tmp_gvt->nct = 0;
|
|
tmp_gvt->collseq = NULL;
|
|
tmp_gvt->regcnt = 1;
|
|
memcpy(tmp_gvt->gvname.var_name.addr, gvent.var_name.addr, gvent.var_name.len);
|
|
tmp_gvt->gvname.var_name.len = gvent.var_name.len;
|
|
tmp_gvt->gvname.hash_code = gvent.hash_code;
|
|
} else
|
|
{
|
|
assert(gv_cur_region->max_key_size <= MAX_KEY_SZ);
|
|
tmp_gvt = (gv_namehead *)targ_alloc(gv_cur_region->max_key_size, &gvent, gv_cur_region);
|
|
}
|
|
gvnh_reg = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));
|
|
gvnh_reg->gvt = tmp_gvt;
|
|
gvnh_reg->gd_reg = gv_cur_region;
|
|
if (NULL != tabent)
|
|
{ /* Since the global name was found but gv_target was null and now we created a new gv_target,
|
|
* the hash table key must point to the newly created gv_target->gvname. */
|
|
tabent->key = tmp_gvt->gvname;
|
|
tabent->value = (char *)gvnh_reg;
|
|
} else
|
|
{
|
|
added = add_hashtab_mname((hash_table_mname *)addr->tab_ptr, &tmp_gvt->gvname, gvnh_reg, &tabent);
|
|
assert(added);
|
|
}
|
|
gv_target = tmp_gvt; /* now that any error possibilities (out-of-memory issues in malloc/add_hashtab_mname)
|
|
* are all done, it is safe to set gv_target. Setting it before could casue gv_target
|
|
* and gv_currkey to get out of sync in case of an error condition.
|
|
*/
|
|
}
|
|
if ((keylen = gvent.var_name.len + 2) > gv_cur_region->max_key_size) /* caution: embedded assignment of "keylen" */
|
|
{
|
|
assert(ARRAYSIZE(format_key) >= (1 + gvent.var_name.len));
|
|
format_key[0] = '^';
|
|
memcpy(&format_key[1], gvent.var_name.addr, gvent.var_name.len);
|
|
csa = &FILE_INFO(gv_cur_region)->s_addrs;
|
|
rts_error_csa(CSA_ARG(csa) VARLSTCNT(10) ERR_KEY2BIG, 4, keylen, (int4)gv_cur_region->max_key_size,
|
|
REG_LEN_STR(gv_cur_region), ERR_GVIS, 2, 1 + gvent.var_name.len, format_key);
|
|
}
|
|
memcpy(gv_currkey->base, gvent.var_name.addr, gvent.var_name.len);
|
|
gv_currkey->base[gvent.var_name.len] = 0;
|
|
gvent.var_name.len++;
|
|
gv_currkey->base[gvent.var_name.len] = 0;
|
|
gv_currkey->end = gvent.var_name.len;
|
|
gv_currkey->prev = 0;
|
|
change_reg();
|
|
return;
|
|
}
|