int op_readfl(mval *v, int4 length, int4 timeout) { int4 stat; /* status */ size_t cnt, insize, outsize; char *start_ptr, *save_ptr; unsigned char *temp_ch; error_def(ERR_TEXT); error_def(ERR_RDFLTOOSHORT); error_def(ERR_RDFLTOOLONG); if (timeout < 0) timeout = 0; if (length <= 0) rts_error(VARLSTCNT(1) ERR_RDFLTOOSHORT); if (length > MAX_STRLEN) rts_error(VARLSTCNT(1) ERR_RDFLTOOLONG); assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); if (stringpool.free + length + ESC_LEN > stringpool.top) stp_gcol(length + ESC_LEN); v->mvtype = MV_STR; v->str.addr = (char *)stringpool.free; v->str.len = 0; active_device = io_curr_device.in; stat = (io_curr_device.in->disp_ptr->readfl)(v, length, timeout); stringpool.free += v->str.len; assert((int4)v->str.len <= length); assert(stringpool.free <= stringpool.top); if (DEFAULT_CODE_SET != active_device->in_code_set) { cnt = insize = outsize = v->str.len; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); if (cnt > stringpool.top - stringpool.free) stp_gcol(cnt); temp_ch = stringpool.free; save_ptr = v->str.addr; start_ptr = (char *)temp_ch; stringpool.free += cnt; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); ICONVERT(active_device->input_conv_cd, (unsigned char **)&(v->str.addr), &insize, &temp_ch, &outsize); v->str.addr = start_ptr; } active_device = 0; if (NO_M_TIMEOUT != timeout) return (stat); return FALSE; }
int iomb_read(mval *v,int4 t) { io_desc *io_ptr; d_mb_struct *mb_ptr; int status; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); io_ptr = io_curr_device.in; mb_ptr = (d_mb_struct *) io_ptr->dev_sp; if (stringpool.free + mb_ptr->maxmsg > stringpool.top) stp_gcol (mb_ptr->maxmsg); v->str.addr = (char *)stringpool.free; status = TRUE; assert (io_ptr->state == dev_open); if (mb_ptr->in_top == mb_ptr->in_pos) status = iomb_dataread(t); memcpy(v->str.addr,mb_ptr->in_pos,(v->str.len = INTCAST(mb_ptr->in_top - mb_ptr->in_pos))); mb_ptr->in_pos = mb_ptr->in_top = mb_ptr->inbuf; io_ptr->dollar.x = 0; io_ptr->dollar.y++; return status; }
int gtm_conv(UConverter* from, UConverter* to, mstr *src, char* dstbuff, int* bufflen) { char *dstptr, *dstbase, *srcptr; const char *ichset; int dstlen, src_charlen, srclen; UErrorCode status, status1; if (0 == src->len) return 0; if (NULL == dstbuff) { /* Compute the stringpool buffer space needed for conversion given that source * is encoded in the ichset representation. The ICU functions ucnv_getMinCharSize() * and ucnv_getMaxCharSize() are used to compute the minimum and maximum number of * bytes required per UChar if converted from/to ichset/ochset respectively */ src_charlen = (src->len / ucnv_getMinCharSize(from)) + 1; /* number of UChar's from ichset */ dstlen = UCNV_GET_MAX_BYTES_FOR_STRING(src_charlen, ucnv_getMaxCharSize(to)); dstlen = (dstlen > MAX_STRLEN) ? MAX_STRLEN : dstlen; if (stringpool.free + dstlen > stringpool.top) stp_gcol(dstlen); dstbase = (char *)stringpool.free; } else { dstbase = dstbuff; dstlen = *bufflen; } srcptr = src->addr; srclen = (int)src->len; dstptr = dstbase; status = U_ZERO_ERROR; /* initialization to "success" is required by ICU */ ucnv_convertEx(to, from, &dstptr, dstptr + dstlen, (const char**)&srcptr, srcptr + srclen, NULL, NULL, NULL, NULL, TRUE, TRUE, &status); if (U_FAILURE(status)) { if (U_BUFFER_OVERFLOW_ERROR == status) { /* translation requires more space than the maximum allowed GT.M string size */ if (NULL == dstbuff) rts_error(VARLSTCNT(1) ERR_MAXSTRLEN); else { /* Insufficient buffer passed. Return the required buffer length */ src_charlen = (srclen / ucnv_getMinCharSize(from)) + 1; *bufflen = UCNV_GET_MAX_BYTES_FOR_STRING(src_charlen, ucnv_getMaxCharSize(to)); return -1; } } status1 = U_ZERO_ERROR; ichset = ucnv_getName(from, &status1); assert(U_SUCCESS(status1)); UTF8_BADCHAR(1,(unsigned char *) (srcptr - 1), NULL,STRLEN(ichset), ichset); } return (int) (dstptr - dstbase); }
void op_fnzbitxor(mval *dst, mval *bitstr1, mval *bitstr2) { int n, str_len1, str_len2, new_str_len; unsigned char *byte_1, *byte_n; unsigned char *byte1_1, *byte1_n, byte1_len; unsigned char *byte2_1, *byte2_n, byte2_len; error_def(ERR_INVBITSTR); MV_FORCE_STR(bitstr1); MV_FORCE_STR(bitstr2); if (!bitstr1->str.len || !bitstr2->str.len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); byte1_len = *(unsigned char *)bitstr1->str.addr; str_len1 = (bitstr1->str.len - 1) * 8; if (7 < byte1_len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); byte2_len = *(unsigned char *)bitstr2->str.addr; str_len2 = (bitstr2->str.len -1) * 8; if (7 < byte2_len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); if (str_len1 - byte1_len > str_len2 - byte2_len) new_str_len = str_len2 - byte2_len; else new_str_len = str_len1 - byte1_len; n = (new_str_len + 7)/8 ; if (stringpool.top - stringpool.free < n + 1) stp_gcol(n + 1); byte_1 = (unsigned char *)stringpool.free; *byte_1 = n * 8 - new_str_len; byte1_1 = (unsigned char *)bitstr1->str.addr; byte2_1 = (unsigned char *)bitstr2->str.addr; for(byte_n = byte_1 + 1, byte1_n = byte1_1 + 1, byte2_n = byte2_1 + 1 ; byte_n <= (byte_1 + n); byte_n++, byte1_n++, byte2_n++) { *byte_n = *byte1_n ^ *byte2_n; } *--byte_n &= mask[*byte_1]; dst->mvtype = MV_STR; dst->str.addr = (char *)stringpool.free; dst->str.len = n + 1; stringpool.free += n + 1; }
void get_command_line(mval *result, boolean_t zcmd_line) { int first_item, len, word_cnt; unsigned char *cp; void stp_gcol(); result->mvtype = MV_STR; len = -1; /* to compensate for no space at the end */ if (cmd_cnt > 1) { first_item = 1; if (zcmd_line) { /* $ZCMDLINE returns the processed command line. Remove "-direct" and/or "-run <runarg>" from cmd line */ cp = (unsigned char *)cmd_arg[1]; if ('-' == *cp++) { first_item++; if ('r' == TOLOWER(*cp)) first_item++; } } for (word_cnt = first_item; word_cnt < cmd_cnt; word_cnt++) len += strlen(cmd_arg[word_cnt]) + 1; /* include space between arguments */ } if (0 >= len) { result->str.len = 0; return; } if (stringpool.free + len > stringpool.top) stp_gcol(len); cp = stringpool.free; stringpool.free += len; result->str.addr = (char *)cp; result->str.len = len; for (word_cnt = first_item; ; *cp++ = ' ') { len = strlen(cmd_arg[word_cnt]); memcpy(cp, cmd_arg[word_cnt], len); if (++word_cnt == cmd_cnt) break; cp += len; } assert(cp + len == stringpool.free); return; }
int comp_fini(bool status, mstr *obj, opctype retcode, oprtype *retopr, int src_len) { triple *ref; error_def(ERR_INDEXTRACHARS); if (status && source_column != src_len + 2 && source_buffer[source_column] != '\0') { status = FALSE; stx_error(ERR_INDEXTRACHARS); } if (status) { cg_phase = CGP_RESOLVE; assert(for_stack_ptr == for_stack); if (*for_stack_ptr) tnxtarg(*for_stack_ptr); ref = newtriple(retcode); if (retopr) ref->operand[0] = *retopr; start_fetches(OC_NOOP); resolve_ref(0); /* cannot fail because there are no MLAB_REF's in indirect code */ alloc_reg(); stp_gcol(0); assert(indr_stringpool.base == stringpool.base); indr_stringpool = stringpool; stringpool = rts_stringpool; compile_time = FALSE; ind_code(obj); indr_stringpool.free = indr_stringpool.base; } else { assert(indr_stringpool.base == stringpool.base); indr_stringpool = stringpool; stringpool = rts_stringpool; indr_stringpool.free = indr_stringpool.base; compile_time = FALSE; cg_phase = CGP_NOSTATE; } transform = TRUE; mcfree(); return status; }
oprtype make_gvsubsc(mval *v) { mval w; gv_key *gp; if (stringpool.top - stringpool.free < MAX_SRCLINE + sizeof(gv_key)) { stp_gcol(MAX_SRCLINE + sizeof(gv_key)); } if ((int) stringpool.free & 1) stringpool.free++; /* word align key for structure refs */ gp = (gv_key *) stringpool.free; gp->top = MAX_SRCLINE; gp->end = gp->prev = 0; mval2subsc(v,gp); w.mvtype = MV_STR | MV_SUBLIT; w.str.addr = (char *) gp->base; w.str.len = gp->end + 1; stringpool.free = &gp->base[gp->end + 1]; assert(stringpool.free <= stringpool.top); return put_lit(&w); }
void get_reference(mval *var) { char *end, *start; char extnamdelim[] = "^|\"\"|"; char *extnamsrc, *extnamtop; int maxlen; /* you need to return a double-quote for every single-quote. assume worst case. */ maxlen = MAX_ZWR_KEY_SZ + (!extnam_str.len ? 0 : ((extnam_str.len * 2) + sizeof(extnamdelim))); if (stringpool.free + maxlen > stringpool.top) stp_gcol(maxlen); var->mvtype = MV_STR; start = var->str.addr = (char *)stringpool.free; var->str.len = 0; if (gv_currkey && gv_currkey->end) { if (extnam_str.len) { *start++ = extnamdelim[0]; *start++ = extnamdelim[1]; *start++ = extnamdelim[2]; extnamsrc = &extnam_str.addr[0]; extnamtop = extnamsrc + extnam_str.len; for ( ; extnamsrc < extnamtop; ) { *start++ = *extnamsrc; if ('"' == *extnamsrc++) /* caution : pointer increment side-effect */ *start++ = '"'; } *start++ = extnamdelim[3]; } end = (char *)format_targ_key((unsigned char *)start, MAX_ZWR_KEY_SZ, gv_currkey, TRUE); if (extnam_str.len) /* Note: the next vertical bar overwrites the caret that * was part of he original name of the global variable */ *start = extnamdelim[4]; var->str.len = end - var->str.addr; stringpool.free += var->str.len; } }
void s2pool_align(mstr *string) { int length, align_padlen; if ((length = string->len) == 0) return; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); if (mstr_native_align) align_padlen = PADLEN(stringpool.free, NATIVE_WSIZE); else align_padlen = 0; if (length + align_padlen > stringpool.top - stringpool.free) stp_gcol(length + align_padlen); stringpool.free += align_padlen; memcpy(stringpool.free, string->addr, length); string->addr = (char *)stringpool.free; stringpool.free += length; assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); }
void op_fnzbitnot(mval *dst,mval *bitstr) { int str_len; unsigned char *byte_1, *byte_n, *dist_byte, byte_len; int n; error_def(ERR_INVBITSTR); MV_FORCE_STR(bitstr); if (!bitstr->str.len) rts_error(VARLSTCNT(1) ERR_INVBITSTR); byte_len = *(unsigned char *)bitstr->str.addr; str_len = (bitstr->str.len -1) * 8; if ((byte_len < 0) || (byte_len > 7)) { rts_error(VARLSTCNT(1) ERR_INVBITSTR); } if (stringpool.top - stringpool.free < bitstr->str.len) stp_gcol(bitstr->str.len); byte_1 = (unsigned char *)bitstr->str.addr; dist_byte = (unsigned char *)stringpool.free; *dist_byte = *byte_1; dist_byte++; n = bitstr->str.len; for (byte_n = byte_1 + 1; byte_n <= (byte_1 + n); byte_n++, dist_byte++) { *dist_byte = ~(*byte_n); } dst->mvtype = MV_STR; dst->str.addr = (char *)stringpool.free; dst->str.len = bitstr->str.len; stringpool.free += bitstr->str.len; }
int f_char(oprtype *a, opctype op) { triple *root, *last, *curr; oprtype argv[CHARMAXARGS], *argp; mval v; bool all_lits; char *c; int argc, i; error_def(ERR_FCHARMAXARGS); all_lits = TRUE; argp = &argv[0]; argc = 0; for (;;) { if (!intexpr(argp)) return FALSE; assert(argp->oprclass == TRIP_REF); if (argp->oprval.tref->opcode != OC_ILIT) all_lits = FALSE; argc++; argp++; if (window_token != TK_COMMA) break; advancewindow(); if (argc >= CHARMAXARGS) { stx_error(ERR_FCHARMAXARGS); return FALSE; } } if (all_lits) { if (stringpool.top - stringpool.free < argc) stp_gcol(argc); v.mvtype = MV_STR; v.str.addr = c = (char *) stringpool.free; argp = &argv[0]; for (; argc > 0 ;argc--, argp++) { i = argp->oprval.tref->operand[0].oprval.ilit; if ((i >= 0) && (i < 256)) /* only true for single byte character set */ *c++ = i; } v.str.len = c - v.str.addr; stringpool.free =(unsigned char *) c; s2n(&v); *a = put_lit(&v); return TRUE; } root = maketriple(op); root->operand[0] = put_ilit(argc + 2); curr = newtriple(OC_PARAMETER); curr->operand[0] = put_ilit(0); root->operand[1] = put_tref(curr); last = curr; argp = &argv[0]; for (; argc > 0 ;argc--, argp++) { curr = newtriple(OC_PARAMETER); curr->operand[0] = *argp; last->operand[1] = put_tref(curr); last = curr; } ins_triple(root); *a = put_tref(root); return TRUE; }
void op_fnj3(mval *src,int width,int fract,mval *dst) { int4 n, n1, m; int w, digs, digs_used; int sign; static readonly int4 fives_table[9] = { 500000000, 50000000, 5000000, 500000, 50000, 5000, 500, 50, 5}; unsigned char *cp; error_def(ERR_JUSTFRACT); error_def(ERR_MAXSTRLEN); if (width < 0) width = 0; else if (width > MAX_STRLEN) rts_error(VARLSTCNT(1) ERR_MAXSTRLEN); if (fract < 0) rts_error(VARLSTCNT(1) ERR_JUSTFRACT); w = width + MAX_NUM_SIZE + 2 + fract; /* the literal two above accounts for the possibility of inserting a zero and/or a minus with a width of zero */ if (w > MAX_STRLEN) rts_error(VARLSTCNT(1) ERR_MAXSTRLEN); MV_FORCE_NUM(src); /* need to guarantee that the n2s call will not cause string pool overflow */ if (stringpool.top - stringpool.free < w) stp_gcol(w); sign = 0; cp = stringpool.free; if (src->mvtype & MV_INT) { n = src->m[1]; if (n < 0) { sign = 1; n = -n; } /* Round if necessary */ if (fract < 3) n += fives_table[fract + 6]; /* Compute digs, the number of non-zero leading digits */ if (n < 1000) { digs = 0; /* if we have something like $j(-.01,0,1), the answer should be 0.0, not -0.0 so lets check for that here */ if (sign && fract < 4 && n / ten_pwr[3 - fract] == 0) { sign = 0; n = 0; } else n *= 1000000; } else if (n >= 1000000000) { digs = 7; } else { for (digs = 6; n < 100000000 ; n *= 10 , digs--) ; } /* Do we need leading spaces? */ w = width - sign - (fract != 0) - fract - digs; if (digs == 0) w--; if (w > 0) { memset(cp, ' ', w); cp += w; } if (sign) *cp++ = '-'; if (digs == 0) *cp++ = '0'; else { /* It is possible that when rounding, that we overflowed by one digit. In this case, the left-most digit must be a "1". Take care of this case first. */ if (digs == 7) { *cp++ = '1'; n -= 1000000000; digs = 6; } for ( ; digs > 0 ; digs--) { n1 = n / 100000000; *cp++ = n1 + '0'; n = (n - n1 * 100000000) * 10; } } if (fract) { *cp++ = '.'; for (digs = fract ; digs > 0 && n != 0; digs--) { n1 = n / 100000000; *cp++ = n1 + '0'; n = (n - n1 * 100000000) * 10; } if (digs) { memset(cp, '0', digs); cp += digs; } } } else { digs = src->e - MV_XBIAS; m = src->m[0]; n = src->m[1]; sign = src->sgn; w = digs + fract; if (w < 18 && w >= 0) { if (w < 9) { n += fives_table[w]; if (n >= MANT_HI) { n1 = n / 10; m = m / 10 + ((n - n1 * 10) * MANT_LO); n = n1; digs++; } } else { m += fives_table[w - 9]; if (m >= MANT_HI) { m -= MANT_HI; n++; if (n >= MANT_HI) { n1 = n / 10; m = m / 10 + ((n - n1 * 10) * MANT_LO); n = n1; digs++; } } } } /* if we have something like $j(-.0001,0,1), the answer should be 0.0, not -0.0 */ if (digs <= - fract) { sign = 0; n = m = 0; } w = width - fract - (fract != 0) - sign - (digs < 1 ? 1 : digs); if (w > 0) { memset(cp, ' ', w); cp += w; } if (sign) *cp++ = '-'; digs_used = 0; if (digs < 1) *cp++ = '0'; else { for ( ; digs > 0 && (n != 0 || m != 0); digs--) { n1 = n / 100000000; *cp++ = n1 + '0'; digs_used++; if (digs_used == 9) { n = m; m = 0; } else n = (n - n1 * 100000000) * 10; } if (digs > 0) { memset(cp, '0', digs); cp += digs; } } if (fract) { *cp++ = '.'; if (digs < 0) { digs = - digs; if (digs > fract) digs = fract; memset(cp, '0', digs); cp += digs; fract -= digs; } for (digs = fract ; digs > 0 && (n != 0 || m != 0); digs--) { n1 = n / 100000000; *cp++ = n1 + '0'; digs_used++; if (digs_used == 9) { n = m; m = 0; } else n = (n - n1 * 100000000) * 10; } if (digs) { memset(cp, '0', digs); cp += digs; } } } dst->mvtype = MV_STR; dst->str.addr = (char *) stringpool.free; dst->str.len = (char *) cp - dst->str.addr; stringpool.free = cp; return; }
short iott_readfl (mval *v, int4 length, int4 timeout) /* timeout in seconds */ { boolean_t ret, nonzerotimeout, timed; uint4 mask; unsigned char inchar, *temp; #ifdef __MVS__ unsigned char asc_inchar; #endif int dx, msk_in, msk_num, outlen, rdlen, save_errno, selstat, status, width; int4 msec_timeout; /* timeout in milliseconds */ io_desc *io_ptr; d_tt_struct *tt_ptr; io_terminator outofbands; io_termmask mask_term; unsigned char *zb_ptr, *zb_top; ABS_TIME cur_time, end_time; fd_set input_fd; struct timeval input_timeval; struct timeval save_input_timeval; error_def(ERR_CTRAP); error_def(ERR_IOEOF); error_def(ERR_NOPRINCIO); assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); io_ptr = io_curr_device.in; tt_ptr = (d_tt_struct *)(io_ptr->dev_sp); assert(dev_open == io_ptr->state); iott_flush(io_curr_device.out); width = io_ptr->width; if (stringpool.free + length > stringpool.top) stp_gcol (length); outlen = 0; /* --------------------------------------------------------- * zb_ptr is be used to fill-in the value of $zb as we go * If we drop-out with error or otherwise permaturely, * consider $zb to be null. * --------------------------------------------------------- */ zb_ptr = io_ptr->dollar.zb; zb_top = zb_ptr + sizeof(io_ptr->dollar.zb) - 1; *zb_ptr = 0; io_ptr->esc_state = START; io_ptr->dollar.za = 0; io_ptr->dollar.zeof = FALSE; v->str.len = 0; dx = (int)io_ptr->dollar.x; ret = TRUE; temp = stringpool.free; mask = tt_ptr->term_ctrl; mask_term = tt_ptr->mask_term; if (mask & TRM_NOTYPEAHD) TCFLUSH(tt_ptr->fildes, TCIFLUSH, status); if (mask & TRM_READSYNC) { DOWRITERC(tt_ptr->fildes, &dc1, 1, status); if (0 != status) { io_ptr->dollar.za = 9; rts_error(VARLSTCNT(1) status); } } nonzerotimeout = FALSE; if (NO_M_TIMEOUT == timeout) { timed = FALSE; input_timeval.tv_sec = 100; msec_timeout = NO_M_TIMEOUT; } else { timed = TRUE; input_timeval.tv_sec = timeout; msec_timeout = timeout2msec(timeout); if (!msec_timeout) iott_mterm(io_ptr); else { nonzerotimeout = TRUE; sys_get_curr_time(&cur_time); add_int_to_abs_time(&cur_time, msec_timeout, &end_time); } } input_timeval.tv_usec = 0; do { if (outofband) { outlen = 0; if (!msec_timeout) iott_rterm(io_ptr); outofband_action(FALSE); break; } errno = 0; FD_ZERO(&input_fd); FD_SET(tt_ptr->fildes, &input_fd); assert(0 != FD_ISSET(tt_ptr->fildes, &input_fd)); /* the checks for EINTR below are valid and should not be converted to EINTR * wrapper macros, since the select/read is not retried on EINTR. */ save_input_timeval = input_timeval; /* take a copy and pass it because select() below might change it */ selstat = select(tt_ptr->fildes + 1, (void *)&input_fd, (void *)NULL, (void *)NULL, &save_input_timeval); if (selstat < 0) { if (EINTR != errno) goto term_error; } else if (0 == selstat) { if (timed) { ret = FALSE; break; } continue; /* select() timeout; keep going */ } else if (0 < (rdlen = read(tt_ptr->fildes, &inchar, 1))) /* This read is protected */ { assert(0 != FD_ISSET(tt_ptr->fildes, &input_fd)); /* -------------------------------------------------- * set prin_in_dev_failure to FALSE to indicate that * input device is working now. * -------------------------------------------------- */ prin_in_dev_failure = FALSE; if (tt_ptr->canonical) { if (0 == inchar) { /* -------------------------------------- * This means that the device has hungup * -------------------------------------- */ io_ptr->dollar.zeof = TRUE; io_ptr->dollar.x = 0; io_ptr->dollar.za = 9; io_ptr->dollar.y++; if (io_ptr->error_handler.len > 0) rts_error(VARLSTCNT(1) ERR_IOEOF); break; } else io_ptr->dollar.zeof = FALSE; } if (mask & TRM_CONVERT) NATIVE_CVT2UPPER(inchar, inchar); GETASCII(asc_inchar,inchar); if ((dx >= width) && io_ptr->wrap && !(mask & TRM_NOECHO)) { DOWRITE(tt_ptr->fildes, NATIVE_TTEOL, strlen(NATIVE_TTEOL)); dx = 0; } if ((' ' > INPUT_CHAR) && (tt_ptr->enbld_outofbands.mask & (1 << INPUT_CHAR))) { outlen = 0; io_ptr->dollar.za = 9; std_dev_outbndset(INPUT_CHAR); /* it needs ASCII? */ outofband = 0; if (!msec_timeout) iott_rterm(io_ptr); rts_error(VARLSTCNT(3) ERR_CTRAP, 1, ctrap_action_is); break; } if ((0 != (mask & TRM_ESCAPE)) && ((NATIVE_ESC == inchar) || (START != io_ptr->esc_state))) { if (zb_ptr >= zb_top) { /* $zb overflow */ io_ptr->dollar.za = 2; break; } *zb_ptr++ = inchar; iott_escape(zb_ptr - 1, zb_ptr, io_ptr); *(zb_ptr - 1) = INPUT_CHAR; /* need to store ASCII value */ if (FINI == io_ptr->esc_state) break; if (BADESC == io_ptr->esc_state) { /* Escape sequence failed parse */ io_ptr->dollar.za = 2; break; } /* -------------------------------------------------------------------- * In escape sequence...do not process further, but get next character * -------------------------------------------------------------------- */ } else { /* SIMPLIFY THIS! */ msk_num = (uint4)INPUT_CHAR / NUM_BITS_IN_INT4; msk_in = (1 << ((uint4)INPUT_CHAR % NUM_BITS_IN_INT4)); if (msk_in & mask_term.mask[msk_num]) { *zb_ptr++ = INPUT_CHAR; break; } if (((int)inchar == tt_ptr->ttio_struct->c_cc[VERASE]) && !(mask & TRM_PASTHRU)) { if ((0< outlen) && (0 < dx)) { outlen--; dx--; *temp--; if (!(mask & TRM_NOECHO)) { DOWRITERC(tt_ptr->fildes, eraser, sizeof(eraser), status); if (0 != status) goto term_error; } } } else { if (!(mask & TRM_NOECHO)) { DOWRITERC(tt_ptr->fildes, &inchar, 1, status); if (0 != status) goto term_error; } *temp++ = inchar; outlen++; dx++; } } } else if (0 == rdlen) { if (0 < selstat) { /* this should be the only possibility */ io_ptr->dollar.zeof = TRUE; io_ptr->dollar.x = 0; io_ptr->dollar.za = 0; io_ptr->dollar.y++; if (io_curr_device.in == io_std_device.in) { if (!prin_in_dev_failure) prin_in_dev_failure = TRUE; else { send_msg(VARLSTCNT(1) ERR_NOPRINCIO); stop_image_no_core(); } } if (io_ptr->dollar.zeof) { io_ptr->dollar.za = 9; rts_error(VARLSTCNT(1) ERR_IOEOF); } else { io_ptr->dollar.zeof = TRUE; io_ptr->dollar.za = 0; if (0 < io_ptr->error_handler.len) rts_error(VARLSTCNT(1) ERR_IOEOF); } break; } if (0 == errno) { /* eof */ io_ptr->dollar.zeof = TRUE; io_ptr->dollar.x = 0; io_ptr->dollar.za = 0; io_ptr->dollar.y++; if (0 < io_ptr->error_handler.len) rts_error(VARLSTCNT(1) ERR_IOEOF); break; } } else if (EINTR != errno) /* rdlen < 0 */ goto term_error; if (nonzerotimeout) { sys_get_curr_time(&cur_time); cur_time = sub_abs_time(&end_time, &cur_time); if (0 > cur_time.at_sec) { ret = FALSE; break; } input_timeval.tv_sec = cur_time.at_sec; input_timeval.tv_usec = cur_time.at_usec; } } while (outlen < length); *zb_ptr++ = 0; if (!msec_timeout) { iott_rterm(io_ptr); if (0 == outlen) ret = FALSE; } if (mask & TRM_READSYNC) { DOWRITERC(tt_ptr->fildes, &dc3, 1, status); if (0 != status) { io_ptr->dollar.za = 9; rts_error(VARLSTCNT(1) status); } } if (outofband) { v->str.len = 0; io_ptr->dollar.za = 9; return(FALSE); } v->str.len = outlen; v->str.addr = (char *)stringpool.free; if (!(mask & TRM_NOECHO)) { if ((io_ptr->dollar.x += v->str.len) >= io_ptr->width && io_ptr->wrap) { io_ptr->dollar.y += (io_ptr->dollar.x / io_ptr->width); if (io_ptr->length) io_ptr->dollar.y %= io_ptr->length; io_ptr->dollar.x %= io_ptr->width; if (0 == io_ptr->dollar.x) DOWRITE(tt_ptr->fildes, NATIVE_TTEOL, strlen(NATIVE_TTEOL)); } } return ((short)ret); term_error: save_errno = errno; io_ptr->dollar.za = 9; if (!msec_timeout) iott_rterm(io_ptr); rts_error(VARLSTCNT(1) save_errno); return FALSE; }
void op_fngetjpi(mint jpid, mval *kwd, mval *ret) { error_def (ERR_BADJPIPARAM); struct tms proc_times; int4 info ; int keywd_indx; char upcase[MAX_KEY_LEN]; assert (stringpool.free >= stringpool.base); assert (stringpool.top >= stringpool.free); if (stringpool.top - stringpool.free < MAX_STR) stp_gcol(MAX_STR); MV_FORCE_STR(kwd); if (kwd->str.len == 0) rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, 4, "Null"); if (MAX_KEY < kwd->str.len) rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr); lower_to_upper((uchar_ptr_t)upcase, (uchar_ptr_t)kwd->str.addr, (int)kwd->str.len); keywd_indx = kw_cputim ; /* future enhancement: * (i) since keywords are sorted, we can exit the while loop if 0 < memcmp. * (ii) also, the current comparison relies on kwd->str.len which means a C would imply CPUTIM instead of CSTIME * or CUTIME this ambiguity should probably be removed by asking for an exact match of the full keyword */ while ((0 != memcmp(upcase, key[keywd_indx], kwd->str.len)) && keywd_indx < MAX_KEY) keywd_indx++; if( keywd_indx == MAX_KEY ) { rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr); } if ((kw_isprocalive != keywd_indx) && ((unsigned int)-1 == times(&proc_times))) { rts_error(VARLSTCNT(1) errno); /* need a more specific GTM error message in addition to errno */ return; } switch (keywd_indx) { case kw_cputim: info = proc_times.tms_utime + proc_times.tms_stime + proc_times.tms_cutime + proc_times.tms_cstime; break; case kw_cstime: info = proc_times.tms_cstime; break; case kw_cutime: info = proc_times.tms_cutime; break; case kw_isprocalive: info = (0 != jpid) ? is_proc_alive(jpid, 0) : 1; break; case kw_stime: info = proc_times.tms_stime; break; case kw_utime: info = proc_times.tms_utime; break; case kw_end: default: rts_error(VARLSTCNT(4) ERR_BADJPIPARAM, 2, kwd->str.len, kwd->str.addr); return; } if (kw_isprocalive != keywd_indx) info = (int4)((info * 100) / sysconf(_SC_CLK_TCK)); /* Convert to standard 100 ticks per second */ i2mval(ret, info); }
int compile_pattern(oprtype *opr, bool is_indirect) { ptstr retstr; mval retmval; mstr instr; int status; triple *oldchain, tmpchain, *ref, *triptr; if (is_indirect) { if (shift_gvrefs) { dqinit(&tmpchain, exorder); oldchain = setcurtchain(&tmpchain); if (!indirection(opr)) { setcurtchain(oldchain); return FALSE; } ref = newtriple(OC_INDPAT); newtriple(OC_GVSAVTARG); setcurtchain(oldchain); dqadd(expr_start, &tmpchain, exorder); expr_start = tmpchain.exorder.bl; triptr = newtriple(OC_GVRECTARG); triptr->operand[0] = put_tref(expr_start); } else { if (!indirection(opr)) return FALSE; ref = newtriple(OC_INDPAT); } ref->operand[0] = *opr; *opr = put_tref(ref); return TRUE; } else { instr.addr = (char *)&source_buffer[source_column - 1]; instr.len = strlen(instr.addr); status = patstr(&instr, &retstr, NULL); last_source_column = (short int)(instr.addr - (char *)source_buffer); assert(last_source_column); if (status) { /* status == syntax error when non-zero */ stx_error(status); return FALSE; } retmval.mvtype = MV_STR; retmval.str.len = retstr.len * sizeof(uint4); retmval.str.addr = stringpool.free; if (stringpool.top - stringpool.free < retmval.str.len) stp_gcol(retmval.str.len); memcpy(stringpool.free, &retstr.buff[0], retmval.str.len); stringpool.free += retmval.str.len; *opr = put_lit(&retmval); lexical_ptr = (char *)&source_buffer[last_source_column - 1]; advancewindow(); advancewindow(); return TRUE; } }
short iomt_read (mval *v, int4 t) { error_def (ERR_MTRDTHENWRT); io_desc *dv; d_mt_struct *mt_ptr; #ifdef DP FPRINTF(stderr, ">> iomt_read\n"); #endif assert (stringpool.free >= stringpool.base); assert (stringpool.free <= stringpool.top); dv = io_curr_device.in; mt_ptr = (d_mt_struct *) dv->dev_sp; if (stringpool.free + mt_ptr->record_sz > stringpool.top) stp_gcol (mt_ptr->record_sz); v->str.addr = (char *) stringpool.free; #ifdef UNIX if (mt_ptr->mode != MT_M_READ) { uint4 status; status = iomt_reopen (dv, MT_M_READ, FALSE); if (status != SS_NORMAL) { return (status); } } #endif switch (mt_ptr->last_op) { case mt_rewind: if (mt_ptr->labeled == MTLAB_DOS11) iomt_rddoslab (dv); else if (mt_ptr->labeled == MTLAB_ANSI) iomt_rdansistart (dv); /* CAUTION: FALL THROUGH */ case mt_null: if (iomt_readblk (dv)) { if (mt_ptr->stream) iomt_rdstream (mt_ptr->record_sz, v->str.addr, dv); else iomt_getrec (dv); } break; case mt_read: if (mt_ptr->stream) iomt_rdstream (mt_ptr->record_sz, v->str.addr, dv); else iomt_getrec (dv); break; default: rts_error (VARLSTCNT (1) ERR_MTRDTHENWRT); } if (io_curr_device.in->dollar.zeof) { v->str.len = 0; return TRUE; } if (!mt_ptr->stream) memcpy (v->str.addr, mt_ptr->rec.addr, mt_ptr->rec.len); v->str.len = mt_ptr->rec.len; io_curr_device.in->dollar.x = 0; io_curr_device.in->dollar.y++; mt_ptr->last_op = (mt_ptr->buffptr >= mt_ptr->bufftop) ? mt_null : mt_read; #ifdef DP FPRINTF(stderr, "<< iomt_read\n"); #endif return TRUE; }
int iotcp_readfl(mval *v, int4 width, int4 timeout) /* 0 == width is a flag that the caller is read and the length is not actually fixed */ /* timeout in seconds */ { /* VMS uses the UCX interface; should support others that emulate it */ boolean_t ret, timed, vari; int flags, len, real_errno, save_errno; int i; io_desc *io_ptr; d_tcp_struct *tcpptr; int4 status; int4 msec_timeout; /* timeout in milliseconds */ TID timer_id; ABS_TIME cur_time, end_time, time_for_read, lcl_time_for_read, zero; fd_set tcp_fd; char *errptr; int4 errlen; error_def(ERR_IOEOF); error_def(ERR_TEXT); error_def(ERR_GETSOCKOPTERR); error_def(ERR_SETSOCKOPTERR); #ifdef DEBUG_TCP PRINTF("%s >>>\n", __FILE__); #endif assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); if (0 == width) { /* op_readfl won't do this; must be a call from iotcp_read */ vari = TRUE; width = MAX_READLEN; } else { vari = FALSE; width = (width < MAX_READLEN) ? width : MAX_READLEN; } if (stringpool.free + width > stringpool.top) stp_gcol(width); io_ptr = io_curr_device.in; assert(dev_open == io_ptr->state); tcpptr = (d_tcp_struct *)(io_ptr->dev_sp); if (io_ptr->dollar.x && (TCP_WRITE == tcpptr->lastop)) { /* switching from write to read */ #ifdef C9A06001531 /* pending change request C9A06-001531 */ if (!io_ptr->dollar.za) iotcp_wteol(1, io_ptr); #endif io_ptr->dollar.x = 0; } tcpptr->lastop = TCP_READ; ret = TRUE; timer_id = (TID)iotcp_readfl; out_of_time = FALSE; time_for_read.at_sec = ((0 == timeout) ? 0 : 1); time_for_read.at_usec = 0; if (NO_M_TIMEOUT == timeout) { timed = FALSE; msec_timeout = NO_M_TIMEOUT; } else { timed = TRUE; msec_timeout = timeout2msec(timeout); if (msec_timeout > 0) { /* there is time to wait */ #ifdef UNIX /* set blocking I/O */ FCNTL2(tcpptr->socket, F_GETFL, flags); if (flags < 0) { save_errno = errno; errptr = (char *)STRERROR(errno); rts_error(VARLSTCNT(7) ERR_GETSOCKOPTERR, 5, LEN_AND_LIT("F_GETFL FOR NON BLOCKING I/O"), save_errno, LEN_AND_STR(errptr)); } FCNTL3(tcpptr->socket, F_SETFL, flags & (~(O_NDELAY | O_NONBLOCK)), fcntl_res); if (fcntl_res < 0) { save_errno = errno; errptr = (char *)STRERROR(errno); rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5, LEN_AND_LIT("F_SETFL FOR NON BLOCKING I/O"), save_errno, LEN_AND_STR(errptr)); } #endif sys_get_curr_time(&cur_time); add_int_to_abs_time(&cur_time, msec_timeout, &end_time); start_timer(timer_id, msec_timeout, wake_alarm, 0, NULL); } else out_of_time = TRUE; } for (i = 0, status = 0; status >= 0; ) { FD_ZERO(&tcp_fd); FD_SET(tcpptr->socket, &tcp_fd); assert(0 != FD_ISSET(tcpptr->socket, &tcp_fd)); assert(((1 == time_for_read.at_sec) || (0 == time_for_read.at_sec)) && (0 == time_for_read.at_usec)); /* * the check for EINTR below is valid and should not be converted to an EINTR * wrapper macro, since it might be a timeout. */ lcl_time_for_read = time_for_read; status = tcp_routines.aa_select(tcpptr->socket + 1, (void *)(&tcp_fd), (void *)0, (void *)0, &lcl_time_for_read); if (status > 0) { status = tcp_routines.aa_recv(tcpptr->socket, (char *)(stringpool.free + i), width - i, 0); if ((0 == status) || ((-1 == status) && (ECONNRESET == errno || EPIPE == errno || EINVAL == errno))) { /* lost connection. */ if (0 == status) errno = ECONNRESET; real_errno = errno; status = -2; break; } } if (status < 0) { if (EINTR == errno && FALSE == out_of_time) { /* interrupted by a signal which is not OUR timer, continue looping */ status = 0; } else real_errno = errno; } else real_errno = 0; if (outofband) break; if (timed) { if (msec_timeout > 0) { sys_get_curr_time(&cur_time); cur_time = sub_abs_time(&end_time, &cur_time); if (cur_time.at_sec <= 0) { out_of_time = TRUE; cancel_timer(timer_id); if (status > 0) i += status; break; } } else { if (status > 0) i += status; break; } } if (0 > status) break; i += status; if ((vari && (0 != i)) || (i >= width)) break; } if (EINTR == real_errno) status = 0; /* don't treat a <CTRL-C> or timeout as an error */ if (timed) { if (0 == msec_timeout) { if (0 == status) ret = FALSE; } else { #ifdef UNIX real_errno = errno; FCNTL3(tcpptr->socket, F_SETFL, flags, fcntl_res); if (fcntl_res < 0) { save_errno = errno; errptr = (char *)STRERROR(errno); rts_error(VARLSTCNT(7) ERR_SETSOCKOPTERR, 5, LEN_AND_LIT("F_SETFL FOR RESTORING SOCKET OPTIONS"), save_errno, LEN_AND_STR(errptr)); } errno = real_errno; #endif if (out_of_time && (i < width)) ret = FALSE; else cancel_timer(timer_id); } } if (i > 0) { /* there's somthing to return */ v->str.len = i; v->str.addr = (char *)stringpool.free; if (((io_ptr->dollar.x += i) >= io_ptr->width) && (TRUE == io_ptr->wrap)) { io_ptr->dollar.y += (io_ptr->dollar.x / io_ptr->width); if (0 != io_ptr->length) io_ptr->dollar.y %= io_ptr->length; io_ptr->dollar.x %= io_ptr->width; } } else v->str.len = 0; #ifdef DEBUG_TCP PRINTF("%s <<<\n", __FILE__); #endif len = sizeof("1,") - 1; if (status >= 0) { /* no real problems */ io_ptr->dollar.za = 0; /* the handling of urgent data doesn't work and never has, the design should be changed to use a /URGENT controlnmemonic * because there is really only one character available at a time zero.at_sec = zero.at_usec = 0; FD_ZERO(&tcp_fd); FD_SET(tcpptr->socket, &tcp_fd); if (tcp_routines.aa_select(tcpptr->socket + 1, (void *)(tcpptr->urgent ? &tcp_fd : 0), (void *)0, (void *)(tcpptr->urgent ? 0 : &tcp_fd), &zero) > 0) { memcpy(tcpptr->dollar_device, "1,", len); if (tcpptr->urgent) { memcpy(&tcpptr->dollar_device[len], "No ",sizeof("No ")); len += sizeof("No ") - 1; } memcpy(&tcpptr->dollar_device[len], "Urgent Data", sizeof("Urgent Data")); } else */ memcpy(tcpptr->dollar_device, "0", sizeof("0")); } else { /* there's a significant problem */ if (0 == i) io_ptr->dollar.x = 0; io_ptr->dollar.za = 9; memcpy(tcpptr->dollar_device, "1,", len); errptr = (char *)STRERROR(errno); errlen = STRLEN(errptr); memcpy(&tcpptr->dollar_device[len], errptr, errlen); if (io_ptr->dollar.zeof || -1 == status || 0 < io_ptr->error_handler.len) { io_ptr->dollar.zeof = TRUE; rts_error(VARLSTCNT(6) ERR_IOEOF, 0, ERR_TEXT, 2, errlen, errptr); } else io_ptr->dollar.zeof = TRUE; } return (ret); }
void op_gvquery (mval *v) { int4 size; unsigned char buff[MAX_ZWR_KEY_SZ], *end, *glob_begin; bool found; enum db_acc_method acc_meth; unsigned char *extnamsrc, *extnamdst, *extnamtop; int maxlen; char extnamdelim[] = "^|\"\"|"; mval val; /* We want to turn QUERY into QUERYGET for all types of access methods so that we can cache the value of the key returned * by $QUERY. The value is very likely to be used shortly after $QUERY - Vinaya, Aug 13, 2001 */ acc_meth = gv_cur_region->dyn.addr->acc_meth; if (gv_curr_subsc_null) { if (0 == gv_cur_region->std_null_coll) gv_currkey->base[gv_currkey->prev] = 01; else { gv_currkey->base[gv_currkey->end++]= 1; gv_currkey->base[gv_currkey->end++] = 0; gv_currkey->base[gv_currkey->end] = 0; } } else { /* Note, gv_currkey->prev isn't changed here. We rely on this in gtcmtr_query to distinguish different forms of the key */ gv_currkey->base[gv_currkey->end++]= 1; gv_currkey->base[gv_currkey->end++] = 0; gv_currkey->base[gv_currkey->end] = 0; } switch (acc_meth) { case dba_bg: case dba_mm: found = ((0 != gv_target->root) ? gvcst_query() : FALSE); /* global does not exist if root is 0 */ break; case dba_cm: found = gvcmx_query(&val); /* val ignored currently - Vinaya Aug 13, 2001*/ break; case dba_usr: found = gvusr_query(v); /* $Q result in v for dba_usr, for others, in gv_altkey */ break; default: assert(FALSE); /* why didn't we cover all access methods? */ found = FALSE; break; } v->mvtype = MV_STR; if (found) { if (acc_meth != dba_usr) { if ((end = format_targ_key(&buff[0], MAX_ZWR_KEY_SZ, gv_altkey, TRUE)) == 0) end = &buff[MAX_ZWR_KEY_SZ - 1]; size = (int)(end - &buff[0] - 1); /* exclude ^ */ glob_begin = &buff[1]; /* skip ^ */ } else { size = v->str.len - 1; /* exclude ^ */ glob_begin = (unsigned char *)v->str.addr + 1; /* skip ^ */ } /* Need to return a double-quote for every single-quote; assume worst case. */ /* Account for ^ in both cases - extnam and no extnam */ maxlen = size + ((0 == extnam_str.len) ? 1 : ((extnam_str.len * 2) + (int)(STR_LIT_LEN(extnamdelim)))); if ((stringpool.top - stringpool.free) < maxlen) { v->str.len = 0; /* so stp_gcol ignores otherwise incompletely setup mval */ stp_gcol(maxlen); } extnamdst = stringpool.free; *extnamdst++ = extnamdelim[0]; if (extnam_str.len > 0) { *extnamdst++ = extnamdelim[1]; *extnamdst++ = extnamdelim[2]; for (extnamsrc = (unsigned char *)extnam_str.addr, extnamtop = extnamsrc + extnam_str.len; extnamsrc < extnamtop; ) { *extnamdst++ = *extnamsrc; if ('"' == *extnamsrc++) /* caution : pointer increment side-effect */ *extnamdst++ = '"'; } *extnamdst++ = extnamdelim[3]; *extnamdst++ = extnamdelim[4]; extnam_str.len = 0; } memcpy(extnamdst, glob_begin, size); v->str.len = INTCAST(extnamdst - stringpool.free + size); v->str.addr = (char *)stringpool.free; stringpool.free += v->str.len; assert (v->str.addr < (char *)stringpool.top && v->str.addr >= (char *)stringpool.base); assert (v->str.addr + v->str.len <= (char *)stringpool.top && v->str.addr + v->str.len >= (char *)stringpool.base); } else /* !found */ v->str.len = 0; return; }
void op_fntext(mval *label, int int_exp, mval *rtn, mval *ret) /* label contains label to be located or null string */ /* int_exp contains label offset or line number to reference */ /* ret is used to return the correct string to caller */ { char *cp, *ctop; int i, lbl, letter; mval *temp_rtn, temp_mval; mstr *sld; uint4 stat; rhdtyp *rtn_vector; error_def(ERR_TXTNEGLIN); error_def(ERR_TXTSRCMAT); error_def(ERR_ZLINKFILE); error_def(ERR_ZLMODULE); MV_FORCE_STR(label); MV_FORCE_STR(rtn); temp_rtn = &temp_mval; *temp_rtn = *rtn; /* make a copy of the routine in case the caller used the same mval for rtn and ret */ ret->str.len = 0; /* make ret an emptystring in case the return is by way of the condition handler */ ret->mvtype = MV_STR; sld = (mstr *)NULL; ESTABLISH(fntext_ch); /* to swallow errors and permit an emptystring result */ if ((int_exp == 0) && ((label->str.len == 0) || (*label->str.addr == 0))) stat = ZEROLINE; else stat = get_src_line(temp_rtn, label, int_exp, &sld); if ((FALSE == (stat & CHECKSUMFAIL)) && (FALSE == (stat & NEGATIVELINE))) { if (stat & ZEROLINE) { if (NULL == (rtn_vector = find_rtn_hdr(&temp_rtn->str))) { /* not here, so try to bring it in */ op_zlink(temp_rtn, 0); rtn_vector = find_rtn_hdr(&temp_rtn->str); } if (NULL != rtn_vector) { ret->str.addr = cp = (char *)&rtn_vector->routine_name; for (ctop = cp + sizeof(mident); *cp && cp < ctop; cp++) ; ret->str.len = cp - ret->str.addr; } } else if (NULL != sld) ret->str = *sld; } REVERT; /* If non-empty, copy result to stringpool and * convert any tabs in linestart to spaces */ if (ret->str.len) { if (stringpool.free + ret->str.len > stringpool.top) stp_gcol(ret->str.len); cp = stringpool.free; for (i = 0, lbl = 1; i < ret->str.len; i++) { letter = ret->str.addr[i]; if (lbl) { if ((' ' == letter) || ('\t' == letter)) { letter = ' '; lbl = 0; } *cp++ = letter; } else { if ((' ' != letter) && ('\t' != letter)) { memcpy(cp, &ret->str.addr[i], ret->str.len - i); break; } else *cp++ = ' '; } } ret->str.addr=stringpool.free; stringpool.free += ret->str.len; } return; }
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v) { unsigned char *ptr; short len, temp_short; int4 status, max_reply_len; struct CLB *lnk; unsigned char buff[MAX_ZWR_KEY_SZ], *end; error_def(ERR_BADSRVRNETMSG); error_def(ERR_UNIMPLOP); error_def(ERR_TEXT); error_def(ERR_GVIS); lnk = gv_cur_region->dyn.addr->cm_blk; if (!((link_info *)lnk->usr)->server_supports_long_names && (PRE_V5_MAX_MIDENT_LEN < strlen((char *)gv_currkey->base))) { end = format_targ_key(buff, MAX_ZWR_KEY_SZ, gv_currkey, TRUE); rts_error(VARLSTCNT(14) ERR_UNIMPLOP, 0, ERR_TEXT, 2, LEN_AND_LIT("GT.CM server does not support global names longer than 8 characters"), ERR_GVIS, 2, end - buff, buff, ERR_TEXT, 2, DB_LEN_STR(gv_cur_region)); } lnk->ast = 0; /* all database queries are sync */ lnk->cbl = 1 + /* HDR */ gv_currkey->end + /* key */ sizeof(unsigned short) + /* gv_key.top */ sizeof(unsigned short) + /* gv_key.end */ sizeof(unsigned short) + /* gv_key.prev */ sizeof(unsigned char) + /* gv_key.base */ sizeof(unsigned char) + /* regnum */ sizeof(unsigned short); /* size for variable len SUBSC */ /* the current GT.CM maximum message buffer length is bounded by the size of a short which is 64K. but the * calculation below of lnk->cbl and max_reply_len takes into account the fact that the value that is sent in as * input or read in from the server side can be at most MAX_DBSTRLEN in size. therefore, there is a dependency * that MAX_DBSTRLEN always be less than the GT.CM maximum message buffer length. to ensure this is always the * case, the following assert is added so that whenever MAX_DBSTRLEN is increased, we will fail this assert * and reexamine the code below. */ assert(sizeof(lnk->cbl) == 2); /* assert it is a short. when it becomes a uint4 the assert can be removed * if the macro CM_MAX_BUF_LEN (used below) is changed appropriately */ assert(MAX_DBSTRLEN == (32 * 1024 - 1)); if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code) { if (CMMS_Q_INCREMENT == query_code) { /* 1-byte boolean value of "undef_inhibit" passed to the server for $INCREMENT although, effective V5.0-000, undef_inhibit is no longer relevant as $INCREMENT() implicitly does a $GET() on the global. We keep this byte to ensure compatibility with V5.0-FT01 */ lnk->cbl++; } assert((uint4)lnk->cbl + sizeof(unsigned short) + (uint4)MAX_DBSTRLEN <= (uint4)CM_MAX_BUF_LEN); lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */ } if ((CMMS_Q_GET == query_code) || (CMMS_Q_INCREMENT == query_code) || (CMMS_Q_QUERY == query_code) && ((link_info *)lnk->usr)->query_is_queryget) max_reply_len = lnk->mbl + SIZEOF(unsigned short) + MAX_DBSTRLEN; /* can't predict the length of data value */ else max_reply_len = lnk->mbl; assert(max_reply_len <= (int4)CM_MAX_BUF_LEN); if (stringpool.top < stringpool.free + max_reply_len) stp_gcol(max_reply_len); lnk->mbf = stringpool.free; ptr = lnk->mbf; *ptr++ = query_code; /* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */ temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1; CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); *ptr++ = gv_cur_region->cmx_regnum; CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr, gv_currkey->base, gv_currkey->end + 1); if (CMMS_Q_PUT == query_code || CMMS_Q_INCREMENT == query_code) { ptr += gv_currkey->end + 1; temp_short = (short)v->str.len; assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */ CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr,v->str.addr, v->str.len); if (CMMS_Q_INCREMENT == query_code) { /* UNDEF flag is no longer relevant, but set the flag to ensure compatibility with V5.0-FT01 */ assert(sizeof(undef_inhibit) == 1); ptr[v->str.len] = (unsigned char)undef_inhibit; } } status = cmi_write(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } status = cmi_read(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } ptr = lnk->mbf; if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code) { if (reply_code != *ptr) { if (*ptr != CMMS_E_ERROR) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk,FALSE); } return; } if (reply_code != *ptr) { if ((CMMS_R_UNDEF != *ptr) || ((CMMS_Q_GET != query_code) && (CMMS_Q_INCREMENT != query_code))) { if (CMMS_E_ERROR != *ptr) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk, FALSE); } if (CMMS_Q_INCREMENT == query_code) v->mvtype = 0; /* set the result to be undefined */ return; } ptr++; if (CMMS_R_DATA == reply_code) { CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder); if (1 != temp_short) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); ptr += sizeof(short); status = *ptr; /* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */ MV_FORCE_MVAL(v, status); return; } if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER) { CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); if (1 == len) { MV_FORCE_MVAL(v, 0); } else { if (*ptr++ != gv_cur_region->cmx_regnum) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); /* memcpy(gv_altkey, ptr, len - 1); */ CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); MV_FORCE_MVAL(v, 1); } if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget) { if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget) v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */ return; } } assert(CMMS_R_GET == reply_code || CMMS_R_INCREMENT == reply_code || CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len); CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */ v->mvtype = MV_STR; v->str.len = len; v->str.addr = (char *)stringpool.free; /* we don't need the reply msg anymore, can overwrite reply */ memcpy(v->str.addr, ptr, len); /* so that we don't leave a gaping hole in the stringpool */ stringpool.free += len; return; }
void gvcmz_doop(unsigned char query_code, unsigned char reply_code, mval *v) { unsigned char *ptr; short len, temp_short; int4 status, max_reply_len; struct CLB *lnk; error_def(ERR_BADSRVRNETMSG); lnk = gv_cur_region->dyn.addr->cm_blk; lnk->ast = 0; /* all database queries are sync */ lnk->cbl = 1 + /* HDR */ gv_currkey->end + /* key */ sizeof(unsigned short) + /* gv_key.top */ sizeof(unsigned short) + /* gv_key.end */ sizeof(unsigned short) + /* gv_key.prev */ sizeof(unsigned char) + /* gv_key.base */ sizeof(unsigned char) + /* regnum */ sizeof(unsigned short); /* size for variable len SUBSC */ if (CMMS_Q_PUT == query_code) lnk->cbl += (sizeof(unsigned short) + v->str.len); /* VALUE + length */ if (CMMS_Q_GET == query_code || CMMS_Q_QUERY == query_code && ((link_info *)lnk->usr)->query_is_queryget) max_reply_len = lnk->mbl + sizeof(unsigned short) + MAX_STRLEN; /* can't predict the length of data value */ else max_reply_len = lnk->mbl; if (stringpool.top < stringpool.free + max_reply_len) stp_gcol(max_reply_len); lnk->mbf = stringpool.free; ptr = lnk->mbf; *ptr++ = query_code; /* temp_short = gv_currkey->end + sizeof(gv_key) + 1; */ temp_short = gv_currkey->end + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(unsigned short) + sizeof(char) + 1; CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); *ptr++ = gv_cur_region->cmx_regnum; CM_PUT_SHORT(ptr, gv_currkey->top, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->end, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); CM_PUT_SHORT(ptr, gv_currkey->prev, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr, gv_currkey->base, gv_currkey->end + 1); if (query_code == CMMS_Q_PUT) { ptr += gv_currkey->end + 1; temp_short = (short)v->str.len; assert((int4)temp_short == v->str.len); /* short <- int4 assignment lossy? */ CM_PUT_SHORT(ptr, temp_short, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); memcpy(ptr,v->str.addr, v->str.len); } status = cmi_write(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } if (CMMS_Q_PUT == query_code || CMMS_Q_ZWITHDRAW == query_code || CMMS_Q_KILL == query_code) { status = cmi_read(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } ptr = lnk->mbf; if (reply_code != *ptr) { if (*ptr != CMMS_E_ERROR) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk,FALSE); } return; } status = cmi_read(lnk); if (CMI_ERROR(status)) { ((link_info *)(lnk->usr))->neterr = TRUE; gvcmz_error(query_code, status); return; } ptr = lnk->mbf; if (reply_code != *ptr) { if (CMMS_R_UNDEF != *ptr || CMMS_Q_GET != query_code) { if (CMMS_E_ERROR != *ptr) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); gvcmz_errmsg(lnk, FALSE); } return; } ptr++; if (CMMS_R_DATA == reply_code) { CM_GET_SHORT(temp_short, ptr, ((link_info *)(lnk->usr))->convert_byteorder); if (1 != temp_short) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); ptr += sizeof(short); status = *ptr; /* Temp assignment to status gets rid of compiler warning in MV_FORCE_MVAL macro */ MV_FORCE_MVAL(v, status); return; } if (reply_code == CMMS_R_PREV || reply_code == CMMS_R_QUERY || reply_code == CMMS_R_ORDER) { CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(short); if (1 == len) { MV_FORCE_MVAL(v, 0); } else { if (*ptr++ != gv_cur_region->cmx_regnum) rts_error(VARLSTCNT(1) ERR_BADSRVRNETMSG); /* memcpy(gv_altkey, ptr, len - 1); */ CM_GET_USHORT(gv_altkey->top, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->end, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); CM_GET_USHORT(gv_altkey->prev, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); memcpy(gv_altkey->base, ptr, len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); ptr += (len - 1 - sizeof(unsigned short) - sizeof(unsigned short) - sizeof(unsigned short)); MV_FORCE_MVAL(v, 1); } if (CMMS_R_QUERY != reply_code || 1 == len || !((link_info *)lnk->usr)->query_is_queryget) { if (CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget) v->mvtype = 0; /* force undefined to distinguish $Q returning "" from value of QUERYGET being 0 */ return; } } assert(CMMS_R_GET == reply_code || CMMS_R_QUERY == reply_code && ((link_info *)lnk->usr)->query_is_queryget && 1 < len); CM_GET_SHORT(len, ptr, ((link_info *)(lnk->usr))->convert_byteorder); ptr += sizeof(unsigned short); assert(ptr >= stringpool.base && ptr + len < stringpool.top); /* incoming message is in stringpool */ v->mvtype = MV_STR; v->str.len = len; v->str.addr = (char *)stringpool.free; /* we don't need the reply msg anymore, can overwrite reply */ memcpy(v->str.addr, ptr, len); /* so that we don't leave a gaping hole in the stringpool */ stringpool.free += len; return; }
bool gvcst_get(mval *v) { srch_blk_status *s; enum cdb_sc status; int key_size, data_len; unsigned short rsiz; rec_hdr_ptr_t rp; T_BEGIN_READ_NONTP_OR_TP(ERR_GVGETFAIL); assert(t_tries < CDB_STAGNATE || cs_addrs->now_crit); /* we better hold crit in the final retry (TP & non-TP) */ for (;;) { if (cdb_sc_normal == (status = gvcst_search(gv_currkey, NULL))) { if ((key_size = gv_currkey->end + 1) == gv_target->hist.h[0].curr_rec.match) { rp = (rec_hdr_ptr_t)(gv_target->hist.h[0].buffaddr + gv_target->hist.h[0].curr_rec.offset); GET_USHORT(rsiz, &rp->rsiz); data_len = rsiz + rp->cmpc - sizeof(rec_hdr) - key_size; if (data_len < 0 || (sm_uc_ptr_t)rp + rsiz > gv_target->hist.h[0].buffaddr + ((blk_hdr_ptr_t)gv_target->hist.h[0].buffaddr)->bsiz) { assert(CDB_STAGNATE > t_tries); status = cdb_sc_rmisalign1; } else { if (stringpool.top - stringpool.free < data_len) stp_gcol(data_len); assert(stringpool.top - stringpool.free >= data_len); memcpy(stringpool.free, (sm_uc_ptr_t)rp + rsiz - data_len, data_len); if (0 == dollar_tlevel) { if (0 == t_end(&gv_target->hist, NULL)) continue; } else { status = tp_hist(NULL); if (cdb_sc_normal != status) { t_retry(status); continue; } } v->mvtype = MV_STR; v->str.addr = (char *)stringpool.free; v->str.len = data_len; stringpool.free += data_len; if (cs_addrs->read_write) cs_addrs->hdr->n_gets++; return TRUE; } } else { if (0 == dollar_tlevel) { if (0 == t_end(&gv_target->hist, NULL)) continue; } else { status = tp_hist(NULL); if (cdb_sc_normal != status) { t_retry(status); continue; } } cs_addrs->hdr->n_gets++; return FALSE; } } t_retry(status); } }
/* * ---------------------------------------------------------- * Fast path setpiece when delimiter is one (lit) char replacing * a single piece (last is same as first). * * Arguments: * src - source mval * delim - delimiter char * expr - expression string mval * ind - index in source mval to be set * dst - destination mval where the result is saved. * * Return: * none * ---------------------------------------------------------- */ void op_setp1(mval *src, int delim, mval *expr, int ind, mval *dst) { int len, pfx_str_len, sfx_start_offset, sfx_str_len, rep_str_len, str_len, delim_cnt, pfx_scan_offset; int cpy_cache_lines; unsigned char ldelim, lc, *start_sfx, *str_addr, *end_pfx, *end_src, *start_pfx; boolean_t do_scan; mval dummymval; /* It's value is not used but is part of the call to op_fnp1() */ fnpc *cfnpc, *pfnpc; error_def(ERR_MAXSTRLEN); ldelim = delim; /* Local copy (in unsigned char format) */ do_scan = FALSE; cpy_cache_lines = -1; MV_FORCE_STR(expr); /* Expression to put into piece place */ if (MV_DEFINED(src)) { /* We have 3 possible scenarios: 1) If length of src is too small to cause cacheing by op_fnp1, then just do the work ourselves with no cacheing. 2) If the requested piece is larger than can be cached by op_fnp1, call fnp1 for the maximum piece possible, use the cache info to "prime the pump" and then process the rest of the string ourselves. 3) If the requested piece can be obtained from the cache, call op_fnp1 to validate and rebuild the cache if necessary and then retrieve the necessary info from the fnpc cache. */ MV_FORCE_STR(src); /* Make sure is string prior to length check */ if (FNPC_STRLEN_MIN < src->str.len && FNPC_ELEM_MAX >= ind) { /* 3) Best of all possible cases. The op_fnp1 can do most of our work for us and we can preload the cache on the new string to help its subsequent uses along as well. */ SETWON; op_fnp1(src, delim, ind, &dummymval, FALSE); SETWOFF; cfnpc = &fnpca.fnpcs[src->fnpc_indx - 1]; assert(cfnpc->last_str.addr == src->str.addr); assert(cfnpc->last_str.len == src->str.len); assert(cfnpc->delim == delim); assert(0 < cfnpc->npcs); /* Three more scenarios: #1 piece all in cache, #2 piece would be in cache but ran out of text or #3 piece is beyond what can be cached */ if (cfnpc->npcs >= ind) { /* #1 The piece we want is totally within the cache which is good news */ pfx_str_len = cfnpc->pstart[ind - 1]; delim_cnt = 0; sfx_start_offset = cfnpc->pstart[ind] - 1; /* Include delimiter */ rep_str_len = cfnpc->pstart[ind] - cfnpc->pstart[ind - 1] - 1; /* Replace string length */ sfx_str_len = src->str.len - pfx_str_len - rep_str_len; cpy_cache_lines = ind - 1; } else { /* #2 The string was too short so the cache does not contain our string. This means that the prefix becomes any text that IS in the cache and we set the delim_cnt to be the number of missing pieces so the delimiters can be put in as part of the prefix when we build the new string. */ pfx_str_len = cfnpc->pstart[cfnpc->npcs] - 1; delim_cnt = ind - cfnpc->npcs; sfx_start_offset = 0; sfx_str_len = 0; cpy_cache_lines = cfnpc->npcs; } } else if (FNPC_STRLEN_MIN < src->str.len) { /* 2) We have a element that would not be able to be in the fnpc cache. Go ahead and call op_fnp1 to get cache info up to the maximum and then we will continue the scan on our own. */ SETWON; op_fnp1(src, delim, FNPC_ELEM_MAX, &dummymval, FALSE); SETWOFF; cfnpc = &fnpca.fnpcs[src->fnpc_indx - 1]; assert(cfnpc->last_str.addr == src->str.addr); assert(cfnpc->last_str.len == src->str.len); assert(cfnpc->delim == delim); assert(0 < cfnpc->npcs); if (FNPC_ELEM_MAX > cfnpc->npcs) { /* We ran out of text so the scan is complete. This is basically the same as case #2 above. */ pfx_str_len = cfnpc->pstart[cfnpc->npcs] - 1; delim_cnt = ind - cfnpc->npcs; sfx_start_offset = 0; sfx_str_len = 0; cpy_cache_lines = cfnpc->npcs; } else { /* We have a case where the piece we want cannot be kept in cache. In the special case where there is no more text to handle, we don't need to scan further. Otherwise we prime the pump and continue the scan where the cache left off. */ if ((pfx_scan_offset = cfnpc->pstart[FNPC_ELEM_MAX]) < src->str.len) { /* Normal case where we prime the pump */ do_scan = TRUE; } else { /* Special case -- no more text to scan */ pfx_str_len = cfnpc->pstart[FNPC_ELEM_MAX] - 1; sfx_start_offset = 0; sfx_str_len = 0; } delim_cnt = ind - FNPC_ELEM_MAX; cpy_cache_lines = FNPC_ELEM_MAX; } } else { /* 1) We have a short string where no cacheing happens. Do the scanning work ourselves */ MV_FORCE_STR(src); do_scan = TRUE; pfx_scan_offset = 0; delim_cnt = ind; } } else { /* Source is not defined -- treat as a null string */ pfx_str_len = sfx_str_len = sfx_start_offset = 0; delim_cnt = ind - 1; } /* If we have been forced to do our own scan, do that here. Note the variable pfx_scan_offset has been set to where the scan should begin in the src string and delim_cnt has been set to how many delimiters still need to be processed. */ if (do_scan) { /* Scan the line isolating prefix piece, and end of the piece being replaced */ COUNT_EVENT(cs_small); end_pfx = start_sfx = (unsigned char *)src->str.addr + pfx_scan_offset; end_src = (unsigned char *)src->str.addr + src->str.len; /* The compiler would unroll this loop this way anyway but we want to adjust the start_sfx pointer after the loop but only if we have gone into it at least once. */ if (0 < delim_cnt && start_sfx < end_src) { do { end_pfx = start_sfx; while (start_sfx < end_src && (lc = *start_sfx) != ldelim) start_sfx++; start_sfx++; delim_cnt--; } while (0 < delim_cnt && start_sfx < end_src); /* We have to backup up the suffix start pointer except under the condition that the last character in the buffer is the last delimiter we were looking for. */ if (0 == delim_cnt || start_sfx < end_src || lc != ldelim) --start_sfx; /* Back up suffix to include delimiter char */ /* If we scanned to the end (no text left) and still have delimiters to find, the entire src text should be part of the prefix */ if (start_sfx >= end_src && 0 < delim_cnt) { end_pfx = start_sfx; if (lc == ldelim) /* if last char was delim, reduce delim cnt */ --delim_cnt; } } else { /* If not doing any token finding, then this count becomes the number of tokens to output. Adjust accordingly. */ if (0 > --delim_cnt) delim_cnt = 0; } INCR_COUNT(cs_small_pcs, ind - delim_cnt); /* Now having the following situation: end_pfx -> end of the prefix piece including delimiter start_sfx -> start of suffix piece (with delimiter) or = end_pfx/src->str.addr if none */ pfx_str_len = end_pfx - (unsigned char *)src->str.addr; if (0 > pfx_str_len) pfx_str_len = 0; sfx_start_offset = start_sfx - (unsigned char *)src->str.addr; sfx_str_len = src->str.len - sfx_start_offset; if (0 > sfx_str_len) sfx_str_len = 0; } /* Calculate total string len. delim_cnt has needed padding delimiters for null fields */ str_len = expr->str.len + pfx_str_len + delim_cnt + sfx_str_len; if (str_len > MAX_STRLEN) rts_error(VARLSTCNT(1) ERR_MAXSTRLEN); if (str_len > (stringpool.top - stringpool.free)) stp_gcol(str_len); str_addr = stringpool.free; start_pfx = (unsigned char *)src->str.addr; /* copy prefix */ if (0 < pfx_str_len) { memcpy(str_addr, src->str.addr, pfx_str_len); str_addr += pfx_str_len; } /* copy delimiters */ while (delim_cnt-- > 0) *str_addr++ = ldelim; /* copy expression */ if (0 < expr->str.len) { memcpy(str_addr, expr->str.addr, expr->str.len); str_addr += expr->str.len; } /* copy suffix */ if (0 < sfx_str_len) { memcpy(str_addr, start_pfx + sfx_start_offset, sfx_str_len); str_addr += sfx_str_len; } assert(str_addr - stringpool.free == str_len); dst->mvtype = MV_STR; dst->str.len = str_addr - stringpool.free; dst->str.addr = (char *)stringpool.free; stringpool.free = str_addr; /* If available, update the cache information for this newly created mval to hopefully give it a head start on its next usage. Note that we can only copy over the cache info for the prefix. We cannot include information for the 'expression' except where it starts because the expression could itself contain delimiters that would be found on a rescan. */ if (0 < cpy_cache_lines) { pfnpc = cfnpc; /* pointer for src mval's cache */ do { cfnpc = fnpca.fnpcsteal; /* Next cache element to steal */ if (fnpca.fnpcmax < cfnpc) cfnpc = &fnpca.fnpcs[0]; fnpca.fnpcsteal = cfnpc + 1; /* -> next element to steal */ } while (cfnpc == pfnpc); /* Make sure we don't step on ourselves */ cfnpc->last_str = dst->str; /* Save validation info */ cfnpc->delim = delim; cfnpc->npcs = cpy_cache_lines; dst->fnpc_indx = cfnpc->indx + 1; /* Save where we are putting this element (1 based index in mval so 0 isn't so common) */ memcpy(&cfnpc->pstart[0], &pfnpc->pstart[0], (cfnpc->npcs + 1) * sizeof(unsigned int)); } else { /* No cache available -- just reset index pointer to get fastest cache validation failure */ dst->fnpc_indx = -1; } }
unsigned char *n2s(mval *mv_ptr) { unsigned char *start, *cp, *cp1; int4 exp, n0, m1, m0, tmp; unsigned char lcl_buf[MAX_DIGITS_IN_INT]; if (!MV_DEFINED(mv_ptr)) { underr(mv_ptr); return NULL; } start = stringpool.free; if (start + MAX_NUM_SIZE > stringpool.top) { stp_gcol(MAX_NUM_SIZE); start = stringpool.free; } cp = start; m1 = mv_ptr->m[1]; if (m1 == 0) /* SHOULD THIS BE UNDER THE MV_INT TEST? */ *cp++ = '0'; else if (mv_ptr->mvtype & MV_INT) { if (m1 < 0) { *cp++ = '-'; m1 = -m1; } cp1 = lcl_buf + sizeof(lcl_buf); /* m0 is the integer part */ m0 = m1 / MV_BIAS; /* m1 will become the fractional part */ m1 = m1 - (m0 * MV_BIAS); if (m1 > 0) { for (n0 = 0; n0 < MV_BIAS_PWR; n0++) { tmp = m1; m1 /= 10; tmp -= (m1 * 10); if (tmp) break; } *--cp1 = tmp + '0'; for (n0++; n0 < MV_BIAS_PWR; n0++) { tmp = m1; m1 /= 10; *--cp1 = tmp - (m1 * 10) + '0'; } *--cp1 = '.'; } while (m0 > 0) { tmp = m0; m0 /= 10; *--cp1 = tmp - (m0 * 10) + '0'; } n0 = &lcl_buf[sizeof(lcl_buf)] - cp1; memcpy(cp, cp1, n0); cp += n0; } else { exp = (int4)mv_ptr->e - MV_XBIAS; if (mv_ptr->sgn) *cp++ = '-'; m0 = mv_ptr->m[0]; if (exp < 0) { *cp++ = '.'; for (n0 = exp; n0 < 0; n0++) *cp++ = '0'; } for (; m1; m1 = m0, m0 = 0) { for (n0 = 0; n0 < PACKED_DIGITS; n0++) { if (exp-- == 0) { if (m0 == 0 && m1 == 0) break; *cp++ = '.'; } else if (exp < 0 && m0 == 0 && m1 == 0) break; tmp = m1 / MANT_LO; m1 = (m1 - tmp * MANT_LO) * 10; *cp++ = tmp + '0'; } } while (exp-- > 0) *cp++ = '0'; } mv_ptr->mvtype |= MV_STR; mv_ptr->mvtype &= ~MV_NUM_APPROX; mv_ptr->str.addr = (char *)start; mv_ptr->str.len = cp - start; stringpool.free = cp; return cp; }
void op_gvnext(mval *v) { register char *c; bool found; int4 n; enum db_acc_method acc_meth; acc_meth = gv_cur_region->dyn.addr->acc_meth; /* if the lowest subscript is -1, then make it null */ if ( (gv_currkey->end == gv_currkey->prev + 4) && *(&gv_currkey->base[0] + gv_currkey->prev) == 0x40 && *(&gv_currkey->base[0] + gv_currkey->prev + 1) == 0xEE && *(&gv_currkey->base[0] + gv_currkey->prev + 2) == 0xFF) { *(&gv_currkey->base[0] + gv_currkey->prev) = 01; *(char *)(&gv_currkey->base[0] + gv_currkey->prev + 1) = 0; *(char *)(&gv_currkey->base[0] + gv_currkey->prev + 2) = 0; gv_currkey->end -= 2; } else { if (gv_curr_subsc_null) { *(&gv_currkey->base[0] + gv_currkey->prev) = 01; } else { *(&gv_currkey->base[0] + gv_currkey->end - 1) = 1; *(&gv_currkey->base[0] + gv_currkey->end + 1) = 0; gv_currkey->end++; } } if (acc_meth == dba_bg || acc_meth == dba_mm) { if (gv_target->root) { found = gvcst_order(); }else found = FALSE; /* global does not exist */ }else if (acc_meth == dba_cm) { found = gvcmx_order(); }else { found = gvusr_order(); } v->mvtype = MV_STR; if (!found) { if (stringpool.top - stringpool.free < 2) stp_gcol(2); c = v->str.addr = (char *) stringpool.free; *c++ = '-'; *c = '1'; v->str.len = 2; stringpool.free += 2; } else { gv_altkey->prev = gv_currkey->prev; if (stringpool.top - stringpool.free < MAX_SUBSC_LEN) { if (*(&gv_altkey->base[0] + gv_altkey->prev) != 0xFF) { n = MAX_NUM_SLEN; } else { n = gv_altkey->top - gv_altkey->prev; assert (n > 0); } if (stringpool.top - stringpool.free < n) { stp_gcol (n); } } v->str.addr = (char *) stringpool.free; c = (char *)(&gv_altkey->base[0] + gv_altkey->prev); stringpool.free = gvsub2str ((uchar_ptr_t)c,stringpool.free, FALSE); v->str.len = stringpool.free - (unsigned char *) v->str.addr; assert (v->str.addr < (char *) stringpool.top && v->str.addr >= (char *) stringpool.base); assert (v->str.addr + v->str.len <= (char *) stringpool.top && v->str.addr + v->str.len >= (char *) stringpool.base); } return; }
int omi_prc_def(omi_conn *cptr, char *xend, char *buff, char *bend) { GBLREF bool undef_inhibit; char *bptr; omi_li len; int rv; mval vo, vd, vg; bptr = buff; /* Global Ref */ OMI_LI_READ(&len, cptr->xptr); /* Set up a condition handler */ ESTABLISH_RET(omi_dbms_ch,0); rv = omi_gvextnam(cptr, len.value, cptr->xptr); /* If true, there was an error finding the global reference in the DBMS */ if (rv < 0) { REVERT; return rv; } cptr->xptr += len.value; /* Bounds checking */ if (cptr->xptr > xend) { REVERT; return -OMI_ER_PR_INVMSGFMT; } /* We want to make sure there is plenty of space in the string pool * for all three operations ($ORDER, $GET, $DATA) */ if (cptr->exts & OMI_XTF_NEWOP) stp_gcol(0); /* $DATA */ op_gvdata(&vd); if (!(vd.mvtype & MV_INT)) { REVERT; return -OMI_ER_DB_UNRECOVER; } if (cptr->exts & OMI_XTF_NEWOP) { /* $GET */ undef_inhibit = TRUE; rv = op_gvget(&vg); /* $ORDER */ op_gvorder(&vo); OMI_SI_WRIT(vo.str.len, bptr); if (vo.str.len) { memcpy(bptr, vo.str.addr, vo.str.len); bptr += vo.str.len; } } /* $DATA (buffer write) */ OMI_SI_WRIT(vd.m[1] / MV_BIAS, bptr); if (cptr->exts & OMI_XTF_NEWOP) { /* $GET (buffer write) */ OMI_SI_WRIT((rv ? 1 : 0), bptr); if (!rv || !vg.str.len) OMI_LI_WRIT(0, bptr); else { OMI_LI_WRIT(vg.str.len, bptr); memcpy(bptr, vg.str.addr, vg.str.len); bptr += vg.str.len; } } REVERT; return (int)(bptr - buff); }
void dir_srch (parse_blk *pfil) { struct stat statbuf; int stat_res; lv_val *dir1, *dir2, *tmp; mstr tn; short p2_len; char filb[MAX_FBUFF + 1], patb[sizeof(ptstr)], *c, *lastd, *top, *p2, *c1, ch; mval pat_mval, sub, compare; bool wildname, seen_wd; struct dirent *dent; DIR *dp; plength *plen; int closedir_res; op_kill(zsrch_dir1); op_kill(zsrch_dir2); if (!pfil->b_name) return; /* nothing to search for */ ESTABLISH(dir_ch); pat_mval.mvtype = MV_STR; pat_mval.str.addr = patb; /* patb should be sizeof(ptstr.buff) but instead is sizeof(ptstr) since the C compiler * complains about the former and the latter is just 4 bytes more */ pat_mval.str.len = 0; sub.mvtype = MV_STR; sub.str.len = 0; compare.mvtype = MV_STR; compare.str.len = 0; wildname = (pfil->fnb & F_WILD_NAME) != 0; dir1 = zsrch_dir1; dir2 = zsrch_dir2; if (pfil->fnb & F_WILD_DIR) { seen_wd = FALSE; for (c = pfil->l_dir, lastd = c, top = c + pfil->b_dir; c < top;) { ch = *c++; if (ch == '/') /* note the start of each directory segment */ { if (seen_wd) break; lastd = c; } if (ch == '?' || ch == '*') seen_wd = TRUE; } assert(c <= top); sub.str.addr = pfil->l_dir; sub.str.len = lastd - sub.str.addr; tmp = op_putindx(VARLSTCNT(2) dir1, &sub); tmp->v.mvtype = MV_STR; tmp->v.str.len = 0; for(;;) { tn.addr = lastd; /* wildcard segment */ tn.len = c - lastd - 1; lastd = c; genpat(&tn, &pat_mval); seen_wd = FALSE; p2 = c - 1; for (; c < top;) { ch = *c++; if (ch == '/') /* note the start of each directory segment */ { if (seen_wd) break; lastd = c; } if (ch == '?' || ch == '*') seen_wd = TRUE; } p2_len = lastd - p2; /* length of non-wild segment after wild section */ for (;;) { pop_top(dir1, &sub); /* get next item off the top */ if (!sub.str.len) break; memcpy(filb, sub.str.addr, sub.str.len); filb[sub.str.len] = 0; sub.str.addr = filb; dp = OPENDIR(filb); if (!dp) continue; while(READDIR(dp, dent)) { compare.str.addr = &dent->d_name[0]; compare.str.len = strlen(&dent->d_name[0]); assert(compare.str.len); if ( dent->d_name[0] == '.' && (compare.str.len == 1 || (compare.str.len == 2 && dent->d_name[1] == '.')) ) { continue; /* don't want to read . and .. */ } if (compare.str.len + sub.str.len + p2_len > MAX_FBUFF) continue; if (do_pattern(&compare, &pat_mval)) { /* got a hit */ if (stringpool.free + compare.str.len + sub.str.len + p2_len + 1 > stringpool.top) stp_gcol(compare.str.len + sub.str.len + p2_len + 1); /* concatenate directory and name */ c1 = (char *)stringpool.free; tn = sub.str; s2pool(&tn); tn = compare.str; s2pool(&tn); tn.addr = p2; tn.len = p2_len; s2pool(&tn); *stringpool.free++ = 0; compare.str.addr = c1; compare.str.len += sub.str.len + p2_len; STAT_FILE(compare.str.addr, &statbuf, stat_res); if (-1 == stat_res) continue; if (!(statbuf.st_mode & S_IFDIR)) continue; /* put in results tree */ tmp = op_putindx(VARLSTCNT(2) dir2, &compare); tmp->v.mvtype = MV_STR; tmp->v.str.len = 0; } } CLOSEDIR(dp, closedir_res); } tmp = dir1; dir1 = dir2; dir2 = tmp; if (c >= top) break; } } else { sub.str.addr = pfil->l_dir; sub.str.len = pfil->b_dir; tmp = op_putindx(VARLSTCNT(2) dir1, &sub); tmp->v.mvtype = MV_STR; tmp->v.str.len = 0; } if (wildname) { tn.addr = pfil->l_name; tn.len = pfil->b_name + pfil->b_ext; genpat(&tn, &pat_mval); } for (;;) { pop_top(dir1, &sub); /* get next item off the top */ if (!sub.str.len) break; if (wildname) { memcpy(filb, sub.str.addr, sub.str.len); filb[sub.str.len] = 0; sub.str.addr = filb; dp = OPENDIR(filb); if (!dp) continue; while(READDIR(dp, dent)) { compare.str.addr = &dent->d_name[0]; compare.str.len = strlen(&dent->d_name[0]); if ( dent->d_name[0] == '.' && (compare.str.len == 1 || (compare.str.len == 2 && dent->d_name[1] == '.'))) { continue; /* don't want to read . and .. */ } if (compare.str.len + sub.str.len > MAX_FBUFF) continue; if (do_pattern(&compare, &pat_mval)) { /* got a hit */ if (stringpool.free + compare.str.len + sub.str.len > stringpool.top) stp_gcol(compare.str.len + sub.str.len); /* concatenate directory and name */ c = (char *)stringpool.free; tn = sub.str; s2pool(&tn); tn = compare.str; s2pool(&tn); compare.str.addr = c; compare.str.len += sub.str.len; /* put in results tree */ tmp = op_putindx(VARLSTCNT(2) ind_var, &compare); tmp->v.mvtype = MV_STR; tmp->v.str.len = 0; plen = (plength *)&tmp->v.m[1]; plen->p.pblk.b_esl = compare.str.len; plen->p.pblk.b_dir = sub.str.len; for (c = &compare.str.addr[sub.str.len], c1 = top = &compare.str.addr[compare.str.len]; c < top; ) { if (*c++ != '.') break; } for (; c < top;) { if (*c++ == '.') c1 = c - 1; } plen->p.pblk.b_ext = top - c1; plen->p.pblk.b_name = plen->p.pblk.b_esl - plen->p.pblk.b_dir - plen->p.pblk.b_ext; } } CLOSEDIR(dp, closedir_res); } else { assert(pfil->fnb & F_WILD_DIR); compare.str.addr = pfil->l_name; compare.str.len = pfil->b_name + pfil->b_ext; if (compare.str.len + sub.str.len > MAX_FBUFF) continue; memcpy(filb, sub.str.addr, sub.str.len); filb[sub.str.len] = 0; sub.str.addr = filb; if (stringpool.free + compare.str.len + sub.str.len > stringpool.top) stp_gcol(compare.str.len + sub.str.len); /* concatenate directory and name */ c1 = (char *)stringpool.free; tn = sub.str; s2pool(&tn); tn = compare.str; s2pool(&tn); compare.str.addr = c1; compare.str.len += sub.str.len; /* put in results tree */ tmp = op_putindx(VARLSTCNT(2) ind_var, &compare); tmp->v.mvtype = MV_STR; tmp->v.str.len = 0; plen = (plength *)&tmp->v.m[1]; plen->p.pblk.b_esl = compare.str.len; plen->p.pblk.b_dir = sub.str.len; plen->p.pblk.b_name = pfil->b_name; plen->p.pblk.b_ext = pfil->b_ext; } } op_kill(zsrch_dir1); op_kill(zsrch_dir2); REVERT; }
short iorm_read (mval *v, int4 timeout) /* timeout in seconds */ { boolean_t ret, timed; int4 msec_timeout; /* timeout in milliseconds */ uint4 width; char inchar, *temp; int flags; int fcntl_res; int4 i; io_desc *io_ptr; d_rm_struct *rm_ptr; int4 status; TID timer_id; error_def(ERR_IOEOF); assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); io_ptr = io_curr_device.in; assert (io_ptr->state == dev_open); rm_ptr = (d_rm_struct*) (io_ptr->dev_sp); if (io_ptr->dollar.x && rm_ptr->lastop == RM_WRITE) { if (!io_ptr->dollar.za) iorm_wteol(1, io_ptr); io_ptr->dollar.x = 0; } rm_ptr->lastop = RM_READ; timer_id = (TID) iorm_read; width = io_ptr->width; if (stringpool.free + width > stringpool.top) stp_gcol (width); i = 0; ret = TRUE; temp = (char*) stringpool.free; out_of_time = FALSE; if (timeout == NO_M_TIMEOUT) { timed = FALSE; msec_timeout = NO_M_TIMEOUT; } else { timed = TRUE; msec_timeout = timeout2msec(timeout); if (msec_timeout > 0) { start_timer(timer_id, msec_timeout, wake_alarm, 0, NULL); } else { out_of_time = TRUE; FCNTL2(rm_ptr->fildes, F_GETFL, flags); FCNTL3(rm_ptr->fildes, F_SETFL, (flags | O_NDELAY), fcntl_res); } } errno = 0; if (rm_ptr->fixed) { /* * the check for EINTR below is valid and should not be converted to an EINTR * wrapper macro, since it might be a timeout. */ DOREADRLTO(rm_ptr->fildes, temp, width, out_of_time, status); if (0 > status) { i = 0; if (errno == EINTR && out_of_time) status = -2; } else i = status; } else { do { if ((status = getc (rm_ptr->filstr)) != EOF) { inchar = (unsigned char) status; if (inchar == NATIVE_NL) break; *temp++ = inchar; i++; } else { inchar = 0; if (errno == 0) status = 0; else if (errno == EINTR) { if (out_of_time) status = -2; else continue; /* Ignore interruption if wasn't our timeout */ } break; } } while (i < width); } if (status == EOF && errno != EINTR) { io_ptr->dollar.za = 9; v->str.len = 0; if ((timed) && (!out_of_time)) cancel_timer(timer_id); rts_error(VARLSTCNT(1) errno); } if (timed) { if (msec_timeout == 0) { FCNTL3(rm_ptr->fildes, F_SETFL, flags, fcntl_res); if (rm_ptr->fifo && status == 0) ret = FALSE; } else { if (out_of_time) ret = FALSE; else cancel_timer(timer_id); } } if (status == 0 && i == 0 && !rm_ptr->fifo) { v->str.len = 0; if (io_ptr->dollar.zeof == TRUE) { io_ptr->dollar.za = 9; rts_error(VARLSTCNT(1) ERR_IOEOF); } io_ptr->dollar.zeof = TRUE; io_ptr->dollar.x = 0; io_ptr->dollar.za = 0; io_ptr->dollar.y++; if (io_ptr->error_handler.len > 0) { rts_error(VARLSTCNT(1) ERR_IOEOF); } } else { v->str.len = i; v->str.addr = (char *) stringpool.free; if (!rm_ptr->fixed && inchar == NATIVE_NL) { io_ptr->dollar.x = 0; io_ptr->dollar.y++; } else if ((io_ptr->dollar.x += i) >= io_ptr->width && io_ptr->wrap) { io_ptr->dollar.y += (io_ptr->dollar.x / io_ptr->width); if(io_ptr->length) io_ptr->dollar.y %= io_ptr->length; io_ptr->dollar.x %= io_ptr->width; } } io_ptr->dollar.za = 0; return((short) ret); }