176 lines
5.4 KiB
C
176 lines
5.4 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"
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include "gtm_fcntl.h"
|
||
|
#include "gtm_string.h"
|
||
|
#include "gtm_stdlib.h"
|
||
|
#include "gtm_termios.h"
|
||
|
|
||
|
#include "io.h"
|
||
|
#include "iottdef.h"
|
||
|
#include "io_params.h"
|
||
|
#include "trmdef.h"
|
||
|
#include "gtmio.h"
|
||
|
#include "stringpool.h"
|
||
|
#include "setterm.h"
|
||
|
#include "getcaps.h"
|
||
|
#include "gtm_isanlp.h"
|
||
|
#include "gtm_conv.h"
|
||
|
#include "gtmimagename.h"
|
||
|
|
||
|
GBLREF int COLUMNS, GTM_LINES, AUTO_RIGHT_MARGIN;
|
||
|
GBLREF uint4 gtm_principal_editing_defaults;
|
||
|
GBLREF io_pair io_std_device;
|
||
|
LITREF unsigned char io_params_size[];
|
||
|
GBLREF boolean_t gtm_utf8_mode;
|
||
|
|
||
|
short iott_open(io_log_name *dev_name, mval *pp, int fd, mval *mspace, int4 timeout)
|
||
|
{
|
||
|
unsigned char ch;
|
||
|
d_tt_struct *tt_ptr;
|
||
|
io_desc *ioptr;
|
||
|
int status, chset_index;
|
||
|
int save_errno;
|
||
|
int p_offset;
|
||
|
mstr chset;
|
||
|
|
||
|
error_def(ERR_NOTERMENV);
|
||
|
error_def(ERR_NOTERMENTRY);
|
||
|
error_def(ERR_NOTERMINFODB);
|
||
|
error_def(ERR_TCGETATTR);
|
||
|
error_def(ERR_BADCHSET);
|
||
|
error_def(ERR_ZINTRECURSEIO);
|
||
|
|
||
|
ioptr = dev_name->iod;
|
||
|
if (ioptr->state == dev_never_opened)
|
||
|
{
|
||
|
dev_name->iod->dev_sp = (void *)malloc(SIZEOF(d_tt_struct) + SIZEOF(struct termios));
|
||
|
memset(dev_name->iod->dev_sp, 0, SIZEOF(d_tt_struct) + SIZEOF(struct termios));
|
||
|
tt_ptr = (d_tt_struct *)dev_name->iod->dev_sp;
|
||
|
tt_ptr->ttio_struct = (struct termios *)((char *)tt_ptr + SIZEOF(d_tt_struct));
|
||
|
tt_ptr->in_buf_sz = TTDEF_BUF_SZ;
|
||
|
tt_ptr->enbld_outofbands.x = 0;
|
||
|
tt_ptr->term_ctrl &= (~TRM_NOECHO);
|
||
|
tt_ptr->ttybuff = (char *)malloc(IOTT_BUFF_LEN);
|
||
|
tt_ptr->default_mask_term = TRUE;
|
||
|
ioptr->ichset = ioptr->ochset = gtm_utf8_mode ? CHSET_UTF8 : CHSET_M; /* default */
|
||
|
}
|
||
|
tt_ptr = (d_tt_struct *)dev_name->iod->dev_sp;
|
||
|
if (tt_ptr->mupintr)
|
||
|
rts_error(VARLSTCNT(1) ERR_ZINTRECURSEIO);
|
||
|
p_offset = 0;
|
||
|
while (*(pp->str.addr + p_offset) != iop_eol)
|
||
|
{
|
||
|
if ((ch = *(pp->str.addr + p_offset++)) == iop_exception)
|
||
|
{
|
||
|
ioptr->error_handler.len = *(pp->str.addr + p_offset);
|
||
|
ioptr->error_handler.addr = (char *)(pp->str.addr + p_offset + 1);
|
||
|
s2pool(&ioptr->error_handler);
|
||
|
break;
|
||
|
} else if (ch == iop_canonical)
|
||
|
tt_ptr->canonical = TRUE;
|
||
|
else if (ch == iop_nocanonical)
|
||
|
tt_ptr->canonical = FALSE;
|
||
|
else if (iop_m == ch)
|
||
|
ioptr->ichset = ioptr->ochset = CHSET_M;
|
||
|
else if (gtm_utf8_mode && iop_utf8 == ch)
|
||
|
ioptr->ichset = ioptr->ochset = CHSET_UTF8;
|
||
|
else if (gtm_utf8_mode && (iop_ipchset == ch || iop_opchset == ch))
|
||
|
{
|
||
|
chset.len = *(pp->str.addr + p_offset);
|
||
|
chset.addr = (char *)(pp->str.addr + p_offset + 1);
|
||
|
chset_index = verify_chset(&chset);
|
||
|
if (CHSET_M == chset_index)
|
||
|
if (iop_ipchset == ch)
|
||
|
ioptr->ichset = CHSET_M;
|
||
|
else
|
||
|
ioptr->ochset = CHSET_M;
|
||
|
else if (CHSET_UTF8 == chset_index)
|
||
|
if (iop_ipchset == ch)
|
||
|
ioptr->ichset = CHSET_UTF8;
|
||
|
else
|
||
|
ioptr->ochset = CHSET_UTF8;
|
||
|
else
|
||
|
rts_error(VARLSTCNT(4) ERR_BADCHSET, 2, chset.len, chset.addr);
|
||
|
}
|
||
|
p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ?
|
||
|
(unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]);
|
||
|
}
|
||
|
if (ioptr->state != dev_open)
|
||
|
{
|
||
|
int status;
|
||
|
char *env_term;
|
||
|
|
||
|
assert(fd >= 0);
|
||
|
tt_ptr->fildes = fd;
|
||
|
status = tcgetattr(tt_ptr->fildes, tt_ptr->ttio_struct);
|
||
|
if (0 != status)
|
||
|
{
|
||
|
save_errno = errno;
|
||
|
if (gtm_isanlp(tt_ptr->fildes) == 0)
|
||
|
rts_error(VARLSTCNT(4) ERR_TCGETATTR, 1, tt_ptr->fildes, save_errno);
|
||
|
}
|
||
|
if (IS_GTM_IMAGE)
|
||
|
/* Only the true runtime runs with the modified terminal settings */
|
||
|
setterm(ioptr);
|
||
|
status = getcaps(tt_ptr->fildes);
|
||
|
if (1 != status)
|
||
|
{
|
||
|
if (status == 0)
|
||
|
{
|
||
|
env_term = GETENV("TERM");
|
||
|
if (!env_term)
|
||
|
{
|
||
|
rts_error(VARLSTCNT(1) ERR_NOTERMENV);
|
||
|
env_term = "unknown";
|
||
|
}
|
||
|
rts_error(VARLSTCNT(4) ERR_NOTERMENTRY, 2, LEN_AND_STR(env_term));
|
||
|
} else
|
||
|
rts_error(VARLSTCNT(1) ERR_NOTERMINFODB);
|
||
|
}
|
||
|
ioptr->width = COLUMNS;
|
||
|
ioptr->length = GTM_LINES;
|
||
|
ioptr->wrap = (0 == AUTO_RIGHT_MARGIN) ? FALSE : TRUE; /* defensive programming; till we are absolutely, positively
|
||
|
* certain that there are no uses of wrap == TRUE */
|
||
|
tt_ptr->tbuffp = tt_ptr->ttybuff; /* Buffer is now empty */
|
||
|
tt_ptr->discard_lf = FALSE;
|
||
|
if (!io_std_device.in || io_std_device.in == ioptr->pair.in) /* io_std_device.in not set yet in io_init */
|
||
|
{ /* $PRINCIPAL */
|
||
|
tt_ptr->ext_cap = gtm_principal_editing_defaults;
|
||
|
ioptr->ichset = ioptr->ochset = gtm_utf8_mode ? CHSET_UTF8 : CHSET_M; /* default */
|
||
|
} else
|
||
|
tt_ptr->ext_cap = 0;
|
||
|
if (tt_ptr->default_mask_term)
|
||
|
{
|
||
|
memset(&tt_ptr->mask_term.mask[0], 0, SIZEOF(io_termmask));
|
||
|
if (CHSET_M != ioptr->ichset)
|
||
|
{
|
||
|
tt_ptr->mask_term.mask[0] = TERM_MSK_UTF8_0;
|
||
|
tt_ptr->mask_term.mask[4] = TERM_MSK_UTF8_4;
|
||
|
} else
|
||
|
tt_ptr->mask_term.mask[0] = TERM_MSK;
|
||
|
}
|
||
|
ioptr->state = dev_open;
|
||
|
if ((TT_EDITING & tt_ptr->ext_cap) && !tt_ptr->recall_buff.addr)
|
||
|
{
|
||
|
assert(tt_ptr->in_buf_sz);
|
||
|
tt_ptr->recall_buff.addr = malloc(tt_ptr->in_buf_sz);
|
||
|
tt_ptr->recall_size = tt_ptr->in_buf_sz;
|
||
|
tt_ptr->recall_buff.len = 0; /* nothing in buffer */
|
||
|
tt_ptr->recall_width = 0;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|