void bx_boollit_tail(triple *t, boolean_t jmp_type_one, boolean_t jmp_to_next, boolean_t sense, oprtype *addr) /* search the Boolean in t (recursively) for literal leaves; the logic is similar to bx_tail * the rest of the arguments parallel those in bx_boolop and used primarily handling basic Boolean operations (ON, NOR, AND, NAND) * to get the jump target and sense right for the left-hand operand of the operation * jmp_type_one gives the sense of the jump associated with the first operand * jmp_to_next gives whether we need a second jump to complete the operation * sense gives the sense of the requested operation * *addr points the operand for the jump and is eventually used by logic back in the invocation stack to fill in a target location */ { boolean_t sin[ARRAYSIZE(t->operand)], tv[ARRAYSIZE(t->operand)]; int com, comval, dummy, j, neg, num, tvr; mval *mv, *v[ARRAYSIZE(t->operand)]; opctype c; oprtype *i, *p; triple *cob[ARRAYSIZE(t->operand)], *ref0, *tl[ARRAYSIZE(t->operand)]; assert(OCT_BOOL & oc_tab[t->opcode].octype); assert(TRIP_REF == t->operand[0].oprclass); assert((OC_COBOOL != t->opcode) && (OC_COM != t->opcode) || (TRIP_REF == t->operand[1].oprclass)); for (i = t->operand, j = 0; i < ARRAYTOP(t->operand); i++, j++) { /* checkout an operand to see if we can simplify it */ p = i; com = 0; for (tl[j] = i->oprval.tref; OCT_UNARY & oc_tab[(c = tl[j]->opcode)].octype; tl[j] = p->oprval.tref) { /* find the real object of affection; WARNING assignment above */ assert((TRIP_REF == tl[j]->operand[0].oprclass) && (NO_REF == tl[j]->operand[1].oprclass)); com ^= (OC_COM == c); /* if we make a recursive call below, COM matters, but NEG and FORCENUM don't */ p = &tl[j]->operand[0]; } if (OCT_ARITH & oc_tab[c].octype) ex_tail(p); /* chained arithmetic */ else if (OCT_BOOL & oc_tab[c].octype) { /* recursively check an operand */ sin[j] = sense; p = addr; if (!j && !(OCT_REL & oc_tab[t->opcode].octype)) { /* left hand operand of parent */ sin[j] = jmp_type_one; if (jmp_to_next) { /* left operands need extra attention to decide between jump next or to the end */ p = (oprtype *)mcalloc(SIZEOF(oprtype)); *p = put_tjmp(t); } } bx_boollit(tl[j], sin[j] ^ com, p); } if ((OC_JMPTRUE != tl[j]->opcode) && (OC_JMPFALSE != tl[j]->opcode) && (OC_LIT != tl[j]->opcode)) return; /* this operation doesn't qualify */ com = comval = neg = num = 0; cob[j] = NULL; for (ref0 = i->oprval.tref; OCT_UNARY & oc_tab[(c = ref0->opcode)].octype; ref0 = ref0->operand[0].oprval.tref) { /* we may be able to clean up this operand; WARNING assignment above */ assert((TRIP_REF == ref0->operand[0].oprclass) && (NO_REF == ref0->operand[1].oprclass)); num += (OC_FORCENUM == c); com += (OC_COM == c); if (!com) /* "outside" com renders neg mute */ neg ^= (OC_NEG == c); if (!comval && (NULL == cob[j])) { if (comval = (OC_COMVAL == c)) /* WARNING assignment */ { if (ref0 != t->operand[j].oprval.tref) dqdel(t->operand[j].oprval.tref, exorder); t->operand[j].oprval.tref = tl[j]; /* need mval: no COBOOL needed */ } else if (OC_COBOOL == c) { /* the operand needs a COBOOL in case its operator remains unresolved */ cob[j] = t->operand[j].oprval.tref; if (ref0 == cob[j]) continue; /* already where it belongs */ cob[j]->opcode = OC_COBOOL; cob[j]->operand[0].oprval.tref = tl[j]; } else if (ref0 == t->operand[j].oprval.tref) continue; } dqdel(ref0, exorder); } assert(ref0 == tl[j]); if (!comval && (NULL == cob[j]) && (tl[j] != t->operand[j].oprval.tref)) { /* left room for a COBOOL, but there's no need */ dqdel(t->operand[j].oprval.tref, exorder); t->operand[j].oprval.tref = tl[j]; } if ((OC_JMPTRUE == ref0->opcode) || (OC_JMPFALSE == ref0->opcode)) { /* switch to a literal representation of TRUE / FALSE */ assert(INDR_REF == ref0->operand[0].oprclass); ref0->operand[1] = ref0->operand[0]; /* track info as we switch opcode */ PUT_LITERAL_TRUTH((sin[j] ? OC_JMPFALSE : OC_JMPTRUE) == ref0->opcode, ref0); ref0->opcode = OC_LIT; com = 0; /* already accounted for by sin */ } assert((OC_LIT == ref0->opcode) && (MLIT_REF == ref0->operand[0].oprclass)); v[j] = &ref0->operand[0].oprval.mlit->v; if (com) { /* any complement reduces the literal value to [unsigned] 1 or 0 */ unuse_literal(v[j]); tv[j] = (0 == v[j]->m[1]); assert(ref0 == tl[j]); PUT_LITERAL_TRUTH(tv[j], ref0); v[j] = &ref0->operand[0].oprval.mlit->v; num = 0; /* any complement trumps num */ } if (neg || num) { /* get literal into uniform state */ unuse_literal(v[j]); mv = (mval *)mcalloc(SIZEOF(mval)); *mv = *v[j]; if (neg) { if (MV_INT & mv->mvtype) { if (0 != mv->m[1]) mv->m[1] = -mv->m[1]; else mv->sgn = 0; } else if (MV_NM & mv->mvtype) mv->sgn = !mv->sgn; } else s2n(mv); n2s(mv); v[j] = mv; assert(ref0 == tl[j]); put_lit_s(v[j], ref0); } } assert(tl[0] != tl[1]); /* start processing a live one */ for (tvr = j, j = 0; j < tvr; j++) { /* both arguments are literals, so do the operation at compile time */ if (NULL != cob[j]) dqdel(cob[j], exorder); v[j] = &tl[j]->operand[0].oprval.mlit->v; tv[j] = (0 != v[j]->m[1]); unuse_literal(v[j]); tl[j]->opcode = OC_NOOP; tl[j]->operand[0].oprclass = NO_REF; } t->operand[1].oprclass = NO_REF; switch (c = t->opcode) /* WARNING assignment */ { /* optimize the Boolean operations here */ case OC_NAND: case OC_AND: tvr = (tv[0] && tv[1]); break; case OC_NOR: case OC_OR: tvr = (tv[0] || tv[1]); break; case OC_NCONTAIN: case OC_CONTAIN: tvr = 1; (void)matchc(v[1]->str.len, (unsigned char *)v[1]->str.addr, v[0]->str.len, (unsigned char *)v[0]->str.addr, &dummy, &tvr); tvr ^= 1; break; case OC_NEQU: case OC_EQU: tvr = is_equ(v[0], v[1]); break; case OC_NFOLLOW: case OC_FOLLOW: tvr = 0 < memvcmp(v[0]->str.addr, v[0]->str.len, v[1]->str.addr, v[1]->str.len); break; case OC_NGT: case OC_GT: tvr = 0 < numcmp(v[0], v[1]); break; case OC_NLT: case OC_LT: tvr = 0 > numcmp(v[0], v[1]); break; case OC_NPATTERN: case OC_PATTERN: tvr = !(*(uint4 *)v[1]->str.addr) ? do_pattern(v[0], v[1]) : do_patfixed(v[0], v[1]); break; case OC_NSORTS_AFTER: case OC_SORTS_AFTER: tvr = 0 < sorts_after(v[0], v[1]); break; default: assertpro(FALSE); } tvr ^= !sense; t->operand[0] = put_indr(addr); t->opcode = tvr ? OC_JMPFALSE : OC_JMPTRUE; return; }
int dse_ksrch(block_id srch, block_id_ptr_t pp, int4 *off, char *targ_key, int targ_len) { cache_rec_ptr_t dummy_cr; int rsize, tmp_cmpc; int4 cmp, dummy_int; ssize_t size; sm_uc_ptr_t blk_id, bp, b_top, key_top, rp, r_top; unsigned short cc, dummy_short; if(!(bp = t_qread(srch, &dummy_int, &dummy_cr))) rts_error_csa(CSA_ARG(cs_addrs) VARLSTCNT(1) ERR_DSEBLKRDFAIL); if (((blk_hdr_ptr_t) bp)->bsiz > cs_addrs->hdr->blk_size) b_top = bp + cs_addrs->hdr->blk_size; else if (((blk_hdr_ptr_t) bp)->bsiz < SIZEOF(blk_hdr)) b_top = bp + SIZEOF(blk_hdr); else b_top = bp + ((blk_hdr_ptr_t) bp)->bsiz; CLEAR_DSE_COMPRESS_KEY; *off = 0; for (rp = bp + SIZEOF(blk_hdr); rp < b_top; rp = r_top) { *off = (int4)(rp - bp); GET_SHORT(dummy_short, &((rec_hdr_ptr_t)rp)->rsiz); rsize = dummy_short; if (rsize < SIZEOF(rec_hdr)) r_top = rp + SIZEOF(rec_hdr); else r_top = rp + rsize; if (r_top > b_top) r_top = b_top; if (r_top - rp < (((blk_hdr_ptr_t)bp)->levl ? SIZEOF(block_id) : MIN_DATA_SIZE) + SIZEOF(rec_hdr)) { *pp = 0; break; } for (key_top = rp + SIZEOF(rec_hdr); key_top < r_top ; ) if (!*key_top++ && !*key_top++) break; if (((blk_hdr_ptr_t)bp)->levl && key_top > (blk_id = r_top - SIZEOF(block_id))) key_top = blk_id; if (EVAL_CMPC((rec_hdr_ptr_t)rp) > patch_comp_count) cc = patch_comp_count; else cc = EVAL_CMPC((rec_hdr_ptr_t)rp); size = (ssize_t)(key_top - rp - SIZEOF(rec_hdr)); if (size > MAX_KEY_SZ - cc) size = MAX_KEY_SZ - cc; if (size < 0) size = 0; memcpy(&patch_comp_key[cc], rp + SIZEOF(rec_hdr), size); patch_comp_count = (int)(cc + size); GET_LONGP(pp, key_top); cmp = memvcmp(targ_key, targ_len, &patch_comp_key[0], patch_comp_count); if (0 > cmp) break; if (!cmp) { if (0 != ((blk_hdr_ptr_t)bp)->levl) break; if (patch_find_root_search) { for (key_top = rp + SIZEOF(rec_hdr); key_top < r_top; ) if (!*key_top++ && !*key_top++) break; GET_LONG(ksrch_root, key_top); } return TRUE; } } patch_path_count++; if (((blk_hdr_ptr_t) bp)->levl && *pp > 0 && *pp < cs_addrs->ti->total_blks && (*pp % cs_addrs->hdr->bplmap) && dse_ksrch(*pp, pp + 1, off + 1, targ_key, targ_len)) return TRUE; return FALSE; }
static bool mu_open_try(io_log_name *naml, io_log_name *tl, mval *pp, mval *mspace) { int4 status; int4 size; mstr tn; /* translated name */ mstr chset_mstr; int oflag; unsigned char ch; int file_des; struct stat outbuf; char *buf, namebuf[LOGNAME_LEN + 1]; d_mt_struct *mt_ptr; int umask_orig, umask_creat; int char_or_block_special; int fstat_res; int save_errno; int p_offset; boolean_t ichset_specified, ochset_specified; error_def(ERR_SYSCALL); mt_ptr = NULL; char_or_block_special = FALSE; file_des = -2; oflag = 0; tn.len = tl->len; if (tn.len > LOGNAME_LEN) tn.len = LOGNAME_LEN; tn.addr = tl->dollar_io; memcpy(namebuf, tn.addr, tn.len); namebuf[tn.len] = '\0'; buf = namebuf; if (0 == naml->iod) { if (0 == tl->iod) { tl->iod = (io_desc *)malloc(sizeof(io_desc)); memset((char*)tl->iod, 0, sizeof(io_desc)); tl->iod->pair.in = tl->iod; tl->iod->pair.out = tl->iod; tl->iod->trans_name = tl; tl->iod->type = n_io_dev_types; p_offset = 0; while(iop_eol != *(pp->str.addr + p_offset)) { ch = *(pp->str.addr + p_offset++); if (iop_sequential == ch) tl->iod->type = rm; if (IOP_VAR_SIZE == io_params_size[ch]) p_offset += *(pp->str.addr + p_offset) + 1; else p_offset += io_params_size[ch]; } } if ((n_io_dev_types == tl->iod->type) && mspace && mspace->str.len) tl->iod->type = us; if (n_io_dev_types == tl->iod->type) { if (0 == memvcmp(tn.addr, tn.len, sys_input.addr, sys_input.len)) { file_des = 0; FSTAT_FILE(file_des, &outbuf, fstat_res); if (-1 == fstat_res) { save_errno = errno; rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fstat()"), CALLFROM, save_errno); } } else { if (0 == memvcmp(tn.addr, tn.len, sys_output.addr, sys_output.len)) { file_des = 1; FSTAT_FILE(file_des, &outbuf, fstat_res); if (-1 == fstat_res) { save_errno = errno; rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fstat()"), CALLFROM, save_errno); } } else if (0 == memvcmp(tn.addr, tn.len, "/dev/null", 9)) tl->iod->type = nl; else if ((-1 == Stat(buf, &outbuf)) && (n_io_dev_types == tl->iod->type)) { if (ENOENT == errno) tl->iod->type = rm; else { save_errno = errno; rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("fstat()"), CALLFROM, save_errno); } } } } if (n_io_dev_types == tl->iod->type) { switch(outbuf.st_mode & S_IFMT) { case S_IFCHR: case S_IFBLK: char_or_block_special = TRUE; break; case S_IFIFO: tl->iod->type = ff; break; case S_IFREG: case S_IFDIR: tl->iod->type = rm; break; case S_IFSOCK: case 0: tl->iod->type = ff; break; default: break; } } naml->iod = tl->iod; } active_device = naml->iod; if ((-2 == file_des) && (dev_open != naml->iod->state) && (us != naml->iod->type) && (tcp != naml->iod->type)) { oflag |= (O_RDWR | O_CREAT | O_NOCTTY); size = 0; p_offset = 0; ichset_specified = ochset_specified = FALSE; while(iop_eol != *(pp->str.addr + p_offset)) { assert((params) *(pp->str.addr + p_offset) < (params)n_iops); switch ((ch = *(pp->str.addr + p_offset++))) { case iop_allocation: if (rm == naml->iod->type) { GET_LONG(size, pp->str.addr + p_offset); size *= 512; } break; case iop_append: if (rm == naml->iod->type) oflag |= O_APPEND; break; case iop_contiguous: break; case iop_newversion: if ((dev_open != naml->iod->state) && (rm == naml->iod->type)) oflag |= O_TRUNC; break; case iop_readonly: oflag &= ~(O_RDWR | O_CREAT | O_WRONLY); oflag |= O_RDONLY; break; case iop_writeonly: oflag &= ~(O_RDWR | O_RDONLY); oflag |= O_WRONLY | O_CREAT; break; case iop_ipchset: #ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != naml->iod->input_conv_cd ) { ICONV_CLOSE_CD(naml->iod->input_conv_cd); } SET_CODE_SET(naml->iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != naml->iod->in_code_set) ICONV_OPEN_CD(naml->iod->input_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); break; #endif if (gtm_utf8_mode) { chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1); chset_mstr.len = *(pp->str.addr + p_offset); SET_ENCODING(naml->iod->ichset, &chset_mstr); ichset_specified = TRUE; } break; case iop_opchset: #ifdef KEEP_zOS_EBCDIC if ( (iconv_t)0 != naml->iod->output_conv_cd) { ICONV_CLOSE_CD(naml->iod->output_conv_cd); } SET_CODE_SET(naml->iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != naml->iod->out_code_set) ICONV_OPEN_CD(naml->iod->output_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); break; #endif if (gtm_utf8_mode) { chset_mstr.addr = (char *)(pp->str.addr + p_offset + 1); chset_mstr.len = *(pp->str.addr + p_offset); SET_ENCODING(naml->iod->ochset, &chset_mstr); ochset_specified = TRUE; } break; case iop_m: case iop_utf8: case iop_utf16: case iop_utf16be: case iop_utf16le: if (gtm_utf8_mode) { naml->iod->ichset = naml->iod->ochset = (iop_m == ch) ? CHSET_M : (iop_utf8 == ch) ? CHSET_UTF8 : (iop_utf16 == ch) ? CHSET_UTF16 : (iop_utf16be == ch) ? CHSET_UTF16BE : CHSET_UTF16LE; ichset_specified = ochset_specified = TRUE; } break; default: break; } if (IOP_VAR_SIZE == io_params_size[ch]) p_offset += *(pp->str.addr + p_offset) + 1; else p_offset += io_params_size[ch]; } if (!ichset_specified) naml->iod->ichset = (gtm_utf8_mode) ? CHSET_UTF8 : CHSET_M; if (!ochset_specified) naml->iod->ochset = (gtm_utf8_mode) ? CHSET_UTF8 : CHSET_M; if (CHSET_M != naml->iod->ichset && CHSET_UTF16 != naml->iod->ichset) get_chset_desc(&chset_names[naml->iod->ichset]); if (CHSET_M != naml->iod->ochset && CHSET_UTF16 != naml->iod->ochset) get_chset_desc(&chset_names[naml->iod->ochset]); /* RW permissions for owner and others as determined by umask. */ umask_orig = umask(000); /* determine umask (destructive) */ (void)umask(umask_orig); /* reset umask */ umask_creat = 0666 & ~umask_orig; /* * the check for EINTR below is valid and should not be converte d to an EINTR * wrapper macro, due to the other errno values being checked. */ while ((-1 == (file_des = OPEN4(buf, oflag, umask_creat, size)))) { if ( EINTR == errno || ETXTBSY == errno || ENFILE == errno || EBUSY == errno || ((mb == naml->iod->type) && (ENXIO == errno))) continue; else break; } if (-1 == file_des) return FALSE; } assert (tcp != naml->iod->type); #ifdef KEEP_zOS_EBCDIC SET_CODE_SET(naml->iod->in_code_set, OUTSIDE_CH_SET); if (DEFAULT_CODE_SET != naml->iod->in_code_set) ICONV_OPEN_CD(naml->iod->input_conv_cd, OUTSIDE_CH_SET, INSIDE_CH_SET); SET_CODE_SET(naml->iod->out_code_set, OUTSIDE_CH_SET); if (DEFAULT_CODE_SET != naml->iod->out_code_set) ICONV_OPEN_CD(naml->iod->output_conv_cd, INSIDE_CH_SET, OUTSIDE_CH_SET); #endif /* smw 99/12/18 not possible to be -1 here */ if (-1 == file_des) { rts_error(VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("open()"), CALLFROM, save_errno); } if (n_io_dev_types == naml->iod->type) { if (isatty(file_des)) naml->iod->type = tt; else if (char_or_block_special && file_des > 2) /* assume mag tape */ naml->iod->type = mt; else naml->iod->type = rm; } assert(naml->iod->type < n_io_dev_types); naml->iod->disp_ptr = &io_dev_dispatch_mupip[naml->iod->type]; active_device = naml->iod; if (dev_never_opened == naml->iod->state) { naml->iod->wrap = DEFAULT_IOD_WRAP; naml->iod->width = DEFAULT_IOD_WIDTH; naml->iod->length = DEFAULT_IOD_LENGTH; naml->iod->write_filter = 0; /* MUPIP should not use FILTER */ } if (dev_open != naml->iod->state) { naml->iod->dollar.x = 0; naml->iod->dollar.y = 0; naml->iod->dollar.za = 0; naml->iod->dollar.zb[0] = 0; } status = (naml->iod->disp_ptr->open)(naml, pp, file_des, mspace, NO_M_TIMEOUT); if (TRUE == status) naml->iod->state = dev_open; else if (dev_open == naml->iod->state) naml->iod->state = dev_closed; if (1 == file_des) naml->iod->dollar.zeof = TRUE; active_device = 0; if (run_time) return (status); return TRUE; }
void op_use(mval *v, mval *p) { char buf1[MAX_TRANS_NAME_LEN]; /* buffer to hold translated name */ io_log_name *nl; /* logical record for passed name */ io_log_name *tl; /* logical record for translated name */ int4 stat; /* status */ mstr tn; /* translated name */ int dollar_zpselect; /* 0 - both, 1 - input only, 2 - output only */ char *c1; /* used to compare $P name */ int nlen; /* len of $P name */ io_log_name *tlp; /* logical record for translated name for $principal */ MV_FORCE_STR(v); MV_FORCE_STR(p); dollar_zpselect = 0; if (io_std_device->in != io_std_device->out) { /* if there is a split $P then determine from the name if it is the value of "$P< /" or "$P> /" if the first then it is $ZPIN so set dollar_zpselect to 1 if the second then it is $ZPOUT so set dollar_zpselect to 2 else set dollar_zpselect to 0 if it is $ZPIN or $ZPOUT get the log_name for $P into nl else use the mval v passed in */ tlp = dollar_principal ? dollar_principal : io_root_log_name->iod->trans_name; nlen = tlp->len; assert(dollar_zpout.len == dollar_zpin.len); if ((nlen + dollar_zpin.len) == v->str.len) { /* passed the length test now compare the 2 pieces, the first one the length of $P and the second $ZPIN or $ZPOUT */ c1 = (char *)tlp->dollar_io; if (!memvcmp(c1, nlen, &(v->str.addr[0]), nlen)) { if (!memvcmp(dollar_zpin.addr, dollar_zpin.len, &(v->str.addr[nlen]), dollar_zpin.len)) dollar_zpselect = 1; else if (!memvcmp(dollar_zpout.addr, dollar_zpout.len, &(v->str.addr[nlen]), dollar_zpout.len)) dollar_zpselect = 2; } } } if (0 == dollar_zpselect) nl = get_log_name(&v->str, NO_INSERT); else nl = get_log_name(&dollar_prin_log, NO_INSERT); if (!nl) { stat = TRANS_LOG_NAME(&v->str, &tn, buf1, SIZEOF(buf1), do_sendmsg_on_log2long); if (stat != SS_NORMAL) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_IONOTOPEN); else { if ((tl = get_log_name(&tn, NO_INSERT)) == 0) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_IONOTOPEN); if (!tl->iod) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_IONOTOPEN); nl = get_log_name(&v->str, INSERT); nl->iod = tl->iod; } } if (nl->iod->state != dev_open) rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_IONOTOPEN); if (dollar_principal && nl->iod == dollar_principal->iod) { /* if device is a GTM_PRINCIPAL synonym */ nl = dollar_principal; } else { /* special case U "" , U 0, U $ZPIN, U $ZPOUT to be equivalent to U $P */ /* $ZPIN or $ZPOUT force nl to "0" */ /* note: "" is always the root */ if (nl == io_root_log_name || ((1 == nl->len) && ('0' == nl->dollar_io[0]))) nl = nl->iod->trans_name; } active_device = nl->iod; io_curr_device = nl->iod->pair; io_curr_device.in->name = nl; if (nl->iod->pair.in == nl->iod->pair.out) (nl->iod->disp_ptr->use)(nl->iod, p); else { if (2 != dollar_zpselect) (nl->iod->disp_ptr->use)(nl->iod, p); if (1 != dollar_zpselect) (nl->iod->pair.out->disp_ptr->use)(nl->iod->pair.out, p); } active_device = 0; return; }