void iorm_flush(io_desc *iod) { d_rm_struct *rm_ptr; rm_ptr = (d_rm_struct *)iod->dev_sp; if (iod->dollar.x && rm_ptr->lastop == RM_WRITE && !iod->dollar.za) iorm_wteol(1,iod); return; }
void iorm_wtff(void) { mstr temp; io_desc *iod; iod = io_curr_device.out; iorm_flush(iod); temp.len = SIZEOF(FORM_FEED) - 1; temp.addr = FORM_FEED; iorm_write(&temp); iorm_wteol(1,iod); iod->dollar.x = 0; iod->dollar.y = 0; }
int iorm_readfl(mval *v, int4 length, int4 timeout) { io_desc *iod; d_rm_struct *d_rm; struct RAB *rab; int4 stat; uint4 len, cp_len; error_def(ERR_IOEOF); assert(timeout >= 0); v->mvtype = MV_STR; iod = io_curr_device.in; d_rm = (d_rm_struct *)io_curr_device.in->dev_sp; /* if write buffer not empty, and there was no error */ if ((FAB$M_PUT == d_rm->r.rab$l_ctx) && d_rm->outbuf != d_rm->outbuf_pos && !iod->dollar.za) iorm_wteol(1, iod); d_rm->r.rab$l_ctx = FAB$M_GET; len = d_rm->inbuf_top - d_rm->inbuf_pos; if ((d_rm->inbuf != d_rm->inbuf_pos) && (0 != len)) { cp_len = fl_copy(length, len); memcpy(v->str.addr, d_rm->inbuf_pos, cp_len); if((d_rm->inbuf_pos += cp_len) >= d_rm->inbuf_top) { d_rm->inbuf_pos = d_rm->inbuf; iod->dollar.y++; iod->dollar.x = 0; } else iod->dollar.x += cp_len; v->str.len = cp_len; } else { rab = &d_rm->r; rab->rab$l_ubf = d_rm->inbuf; d_rm->l_usz = iod->width; stat = iorm_get(iod, timeout); switch (stat) { case RMS$_NORMAL: d_rm->inbuf_top = d_rm->inbuf + d_rm->l_rsz; if (length > d_rm->l_rsz) length = d_rm->l_rsz; v->str.len = length; memcpy(v->str.addr, d_rm->inbuf, length); if ((d_rm->inbuf_pos += length) >= d_rm->inbuf_top) { d_rm->inbuf_pos = d_rm->inbuf; iod->dollar.y++; iod->dollar.x = 0; } else iod->dollar.x += length; iod->dollar.za = 0; break; case RMS$_TMO: v->str.len = 0; iod->dollar.za = 9; return FALSE; case RMS$_EOF: v->str.len = 0; if (iod->dollar.zeof) { iod->dollar.za = 9; rts_error(VARLSTCNT(1) ERR_IOEOF); } iod->dollar.x = 0; iod->dollar.y++; iod->dollar.za = 0; iod->dollar.zeof = TRUE; if (iod->error_handler.len > 0) rts_error(VARLSTCNT(1) ERR_IOEOF); break; default: v->str.len = 0; iod->dollar.za = 9; rts_error(VARLSTCNT(2) stat, rab->rab$l_stv); } } return TRUE; }
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); }
int iorm_read(mval *v, int4 timeout) { io_desc *iod; d_rm_struct *rm_ptr; struct RAB *rab; int4 stat; int len; error_def(ERR_IOEOF); assert(stringpool.free >= stringpool.base); assert(stringpool.free <= stringpool.top); assert(timeout >= 0); iod = io_curr_device.in; rm_ptr = (d_rm_struct *)iod->dev_sp; /* if write buffer not empty, and there was no error */ if ((FAB$M_PUT == rm_ptr->r.rab$l_ctx) && (rm_ptr->outbuf != rm_ptr->outbuf_pos) && !iod->dollar.za) iorm_wteol(1, iod); v->mvtype = MV_STR; rm_ptr->r.rab$l_ctx = FAB$M_GET; if (rm_ptr->inbuf != rm_ptr->inbuf_pos && (0 != (len = rm_ptr->inbuf_top - rm_ptr->inbuf_pos))) { assert(len > 0); ENSURE_STP_FREE_SPACE(len); v->str.addr = stringpool.free; memcpy(v->str.addr, rm_ptr->inbuf_pos, len); rm_ptr->inbuf_pos = rm_ptr->inbuf; v->str.len = len; iod->dollar.x = 0; iod->dollar.y++; } else { /* ensure extra space for pad if not longword aligned */ ENSURE_STP_FREE_SPACE(iod->width + (rm_ptr->largerecord ? SIZEOF(uint4) : 0)); /* need to set usz and make sure width == mrs for fix */ rab = &rm_ptr->r; rab->rab$l_ubf = stringpool.free; stat = iorm_get(iod, timeout); switch (stat) { case RMS$_NORMAL: v->str.addr = stringpool.free; v->str.len = rm_ptr->l_rsz; iod->dollar.x = 0; iod->dollar.y++; iod->dollar.za = 0; break; case RMS$_TMO: v->str.len = 0; iod->dollar.za = 9; return FALSE; case RMS$_EOF: v->str.len = 0; if (iod->dollar.zeof) { iod->dollar.za = 9; rts_error(VARLSTCNT(1) ERR_IOEOF); } iod->dollar.x = 0; iod->dollar.za = 0; iod->dollar.y++; iod->dollar.zeof = TRUE; if (iod->error_handler.len > 0) rts_error(VARLSTCNT(1) ERR_IOEOF); break; default: v->str.len = 0; iod->dollar.za = 9; rts_error(VARLSTCNT(2) stat, rab->rab$l_stv); } } return TRUE; }
void iorm_use(io_desc *iod, mval *pp) { unsigned char c; int4 width, length, blocksize; int4 status; d_rm_struct *rm_ptr; struct RAB *r; struct FAB *f; int p_offset; boolean_t shared_seen = FALSE; error_def(ERR_DEVPARMNEG); error_def(ERR_RMWIDTHPOS); error_def(ERR_RMWIDTHTOOBIG); error_def(ERR_RMNOBIGRECORD); error_def(ERR_RMBIGSHARE); error_def(ERR_MTBLKTOOBIG); error_def(ERR_MTBLKTOOSM); p_offset = 0; rm_ptr = (d_rm_struct *)iod->dev_sp; r = &rm_ptr->r; f = &rm_ptr->f; assert(r->rab$l_fab == f); while (*(pp->str.addr + p_offset) != iop_eol) { assert(*(pp->str.addr + p_offset) < n_iops); switch ((c = *(pp->str.addr + p_offset++))) { case iop_allocation: if (iod->state != dev_open) f->fab$l_alq = *(int4*)(pp->str.addr + p_offset); break; case iop_append: if (iod->state != dev_open) r->rab$l_rop |= RAB$M_EOF; break; case iop_blocksize: if (iod->state != dev_open) { GET_LONG(blocksize, pp->str.addr + p_offset); if (MAX_RMS_ANSI_BLOCK < blocksize) rts_error(VARLSTCNT(1) ERR_MTBLKTOOBIG); else if (MIN_RMS_ANSI_BLOCK > blocksize) rts_error(VARLSTCNT(3) ERR_MTBLKTOOSM, 1, MIN_RMS_ANSI_BLOCK); else f->fab$w_bls = (unsigned short)blocksize; } break; case iop_contiguous: if (iod->state != dev_open) { f->fab$l_fop &= ~FAB$M_CBT; f->fab$l_fop |= FAB$M_CTG; } break; case iop_delete: f->fab$l_fop |= FAB$M_DLT; break; case iop_extension: GET_USHORT(f->fab$w_deq, pp->str.addr + p_offset); break; case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = pp->str.addr + p_offset + 1; s2pool(&iod->error_handler); break; case iop_fixed: if (iod->state != dev_open) rm_ptr->f.fab$b_rfm = rm_ptr->b_rfm = FAB$C_FIX; break; case iop_length: GET_LONG(length, pp->str.addr + p_offset); if (length < 0) rts_error(VARLSTCNT(1) ERR_DEVPARMNEG); iod->length = length; break; case iop_newversion: if (iod->state != dev_open) { f->fab$l_fop |= FAB$M_MXV; f->fab$l_fop &= ~(FAB$M_CIF | FAB$M_SUP); } break; case iop_nosequential: break; case iop_s_protection: rm_ptr->promask &= ~(0x0F << XAB$V_SYS); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_SYS); break; case iop_w_protection: rm_ptr->promask &= ~(0x0F << XAB$V_WLD); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_WLD); break; case iop_g_protection: rm_ptr->promask &= ~(0x0F << XAB$V_GRP); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_GRP); break; case iop_o_protection: rm_ptr->promask &= ~(0x0F << XAB$V_OWN); rm_ptr->promask |= ((~(unsigned char)*(pp->str.addr + p_offset) & 0x0000000F) << XAB$V_OWN); break; case iop_readonly: if (iod->state != dev_open) f->fab$b_fac = FAB$M_GET; break; case iop_noreadonly: if (iod->state != dev_open) f->fab$b_fac = FAB$M_GET | FAB$M_PUT | FAB$M_TRN; break; case iop_recordsize: if (iod->state != dev_open) { GET_LONG(width, pp->str.addr + p_offset); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); iod->width = width; if (MAX_RMS_RECORDSIZE >= width) r->rab$w_usz = f->fab$w_mrs = (unsigned short)width; else if (MAX_STRLEN < width) rts_error(VARLSTCNT(1) ERR_RMWIDTHTOOBIG); else if (!rm_ptr->largerecord) rts_error(VARLSTCNT(1) ERR_RMNOBIGRECORD); rm_ptr->l_usz = rm_ptr->l_mrs = width; } break; case iop_shared: if (iod->state != dev_open) shared_seen = TRUE; break; case iop_spool: f->fab$l_fop |= FAB$M_SPL; break; case iop_submit: f->fab$l_fop |= FAB$M_SCF; break; case iop_rfa: break; case iop_space: if (iod->state == dev_open && f->fab$l_dev & DEV$M_SQD) { GET_LONG(r->rab$l_bkt, pp->str.addr + p_offset); if ((status = sys$space(r, 0, 0)) != RMS$_NORMAL) rts_error(VARLSTCNT(1) status); r->rab$l_bkt = 0; } break; case iop_uic: { unsigned char *ch, ct, *end; uic_struct uic; struct XABPRO *xabpro; ch = pp->str.addr + p_offset; ct = *ch++; end = ch + ct; uic.grp = uic.mem = 0; xabpro = malloc(SIZEOF(struct XABPRO)); *xabpro = cc$rms_xabpro; /* g,m are octal - no matter currently since iorm_open overwrites fab xab */ while (*ch != ',' && ch < end) uic.grp = (10 * uic.grp) + (*ch++ - '0'); if (*ch == ',') { while (++ch < end) uic.mem = (10 * uic.mem) + (*ch - '0'); } xabpro->xab$l_uic = *((int4 *)&uic); f->fab$l_xab = xabpro; break; } case iop_width: if (iod->state == dev_open) { GET_LONG(width, pp->str.addr + p_offset); if (width <= 0) rts_error(VARLSTCNT(1) ERR_RMWIDTHPOS); else if (width <= rm_ptr->l_mrs) { iorm_flush(iod); rm_ptr->l_usz = iod->width = width; if (!rm_ptr->largerecord) r->rab$w_usz = (short)width; iod->wrap = TRUE; } } break; case iop_wrap: iod->wrap = TRUE; break; case iop_nowrap: iod->wrap = FALSE; break; case iop_convert: r->rab$l_rop |= RAB$M_CVT; break; case iop_rewind: if (iod->state == dev_open && rm_ptr->f.fab$l_dev & DEV$M_FOD) { if (iod->dollar.zeof && rm_ptr->outbuf_pos > rm_ptr->outbuf) iorm_wteol(1, iod); sys$rewind(r); iod->dollar.zeof = FALSE; iod->dollar.y = 0; iod->dollar.x = 0; rm_ptr->outbuf_pos = rm_ptr->outbuf; rm_ptr->r.rab$l_ctx = FAB$M_GET; } break; case iop_truncate: r->rab$l_rop |= RAB$M_TPT; break; case iop_notruncate: r->rab$l_rop &= ~RAB$M_TPT; break; case iop_bigrecord: if (iod->state != dev_open) rm_ptr->largerecord = TRUE; break; case iop_nobigrecord: if (iod->state != dev_open) { if (MAX_RMS_RECORDSIZE < rm_ptr->l_mrs) rts_error(ERR_RMNOBIGRECORD); rm_ptr->largerecord = FALSE; } break; case iop_rfm: break; default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[c]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[c]); } if (shared_seen) { f->fab$b_shr = FAB$M_SHRGET; if (rm_ptr->largerecord) { if (f->fab$b_fac & FAB$M_PUT) { rts_error(VARLSTCNT(1) ERR_RMBIGSHARE); } } else if ((f->fab$b_fac & FAB$M_PUT) == FALSE) f->fab$b_shr |= FAB$M_SHRPUT; } }/* eor */