142 lines
3.5 KiB
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;
|
|
}
|