fis-gtm/sr_port/op_dmode.c

142 lines
3.5 KiB
C

/****************************************************************
* *
* Copyright 2001, 2010 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#ifdef UNIX
#include <errno.h>
#endif
#include "gdsroot.h"
#include "gdskill.h"
#include "gdsbt.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsfhead.h"
#include "gdscc.h"
#include "filestruct.h"
#include "jnl.h"
#include "indir_enum.h"
#include "io.h"
#ifdef UNIX
#include "iottdef.h"
#endif
#include "iotimer.h"
#include "rtnhdr.h"
#include "stack_frame.h"
#include "buddy_list.h" /* needed for tp.h */
#include "hashtab_int4.h" /* needed for tp.h */
#include "tp.h"
#include "send_msg.h"
#include "gtmmsg.h" /* for gtm_putmsg() prototype */
#include "op.h"
#include "change_reg.h"
#include "dm_read.h"
#include "tp_change_reg.h"
#include "getzposition.h"
#ifdef DEBUG
#include "have_crit.h" /* for the TPNOTACID_CHECK macro */
#endif
#define DIRECTMODESTR "Entering DIRECT MODE"
GBLREF io_pair io_curr_device;
GBLREF io_pair io_std_device;
GBLREF stack_frame *frame_pointer;
GBLREF unsigned char *restart_pc;
GBLREF unsigned char *restart_ctxt;
error_def(ERR_NOTPRINCIO);
error_def(ERR_NOPRINCIO);
void op_dmode(void)
{
gd_region *save_reg;
mval prompt, dummy, *input_line;
static io_pair save_device;
static bool dmode_intruptd;
# ifdef UNIX
static int loop_cnt = 0;
static int old_errno = 0;
d_tt_struct *tt_ptr;
# endif
static bool kill = FALSE;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
dummy.mvtype = dummy.str.len = 0;
input_line = push_mval(&dummy);
if (dmode_intruptd)
{
if (io_curr_device.out != save_device.out)
{
dec_err(VARLSTCNT(4) ERR_NOTPRINCIO, 2, save_device.out->trans_name->len,
save_device.out->trans_name->dollar_io);
}
} else
{
dmode_intruptd = TRUE;
save_device = io_curr_device;
}
io_curr_device = io_std_device;
if ((TRUE == io_curr_device.in->dollar.zeof) || kill)
op_halt();
/*****************************************************
The following code is meant to avoid an infinite
loop on UNIX systems which occurs when there is an
error in writing the the principal output device here
that results in a call to the condition handler
and an eventual return to this location.
*****************************************************/
# ifdef UNIX
if ((loop_cnt > 0) && (errno == old_errno))
{ /* Tried and failed 2x to write to principal device */
kill = TRUE;
send_msg(VARLSTCNT(1) ERR_NOPRINCIO);
rts_error(VARLSTCNT(1) ERR_NOPRINCIO);
}
++loop_cnt;
old_errno = errno;
# endif
*((INTPTR_T **)&restart_pc) = (INTPTR_T *)CODE_ADDRESS(call_dm);
*((INTPTR_T **)&restart_ctxt) = (INTPTR_T *)GTM_CONTEXT(call_dm);
# ifdef UNIX
loop_cnt = 0;
old_errno = 0;
if (tt == io_curr_device.in->type)
tt_ptr = (d_tt_struct *)io_curr_device.in->dev_sp;
else
tt_ptr = NULL;
if (!tt_ptr || !tt_ptr->mupintr)
# endif
op_wteol(1);
TPNOTACID_CHECK(DIRECTMODESTR);
if (io_curr_device.in->type == tt)
dm_read(input_line);
else
{
prompt.mvtype = MV_STR;
prompt.str = TREF(gtmprompt);
op_write(&prompt);
op_read(input_line, NO_M_TIMEOUT);
}
op_wteol(1);
io_curr_device = save_device;
dmode_intruptd = FALSE;
op_commarg(input_line, indir_linetail);
frame_pointer->type = 0;
}