Working test code:
TEST
use $P:(NOCANONICAL:NOECHO)
w "[" HANG 10 w "].. Enter key:" READ *X:0.1 write X,!
quit
Significant execution events
Launch execution via DO TEST^TMGTEST
resetterm() called.
Stack is
resetterm(io_desc * iod)
dm_read(mval * v)
op_dmode()
tkok3()
[Unknown/Just-In-Time compiled code]
At end of function, we have flag set indicating that setterm() is needed: ttptr->setterm_done_by = 0;
Op_use() called
Stack is
op_use(mval * v, mval * p)
[Unknown/Just-In-Time compiled code]
This sets up ’nl’ variable (logical record for the passed name ‘/dev/pts/1’), which holds a pointer to io data structures.
active_device (global scope var) set to nl->iod
Io_curr_device (global scoped var) set to nl->iod->pair
This next calls iott_use, passing in nl->iod->pair.out received as iod pointer
iott_use(iod) called
tt_ptr set from iod-> dev_sp (Device Structure Pointer)
Current tty settings are queried via tcgetattr(), into variable ‘t’ (type ‘termios’ e.g. ‘term-io-struct’). NOTE: These are the real settings from the TTY system.
Local var mask_in set from iod->pair.in->dev_sp->term_ctrl
Local var mask_term set from iod->pair.in->dev_sp->mask_term. This seems to be the terminator chars used to indicate end of input.
Because of NOCANONICAL, we have this code.
case iop_nocanonical:
tt_ptr->canonical = FALSE;
t.c_lflag &= ~(ICANON);
NOTE: setting t.c_lflag will result in this being sent to TTY system. But state of ‘t’ is not saved in global scope *iod. tt_ptr->canonical is set, but this is not later used. mask_in, mask_term will be saved later, but they are not set here.
Next, because of NOECHO, we have this code
case iop_noecho:
mask_in |= TRM_NOECHO;
break;
NOTE: we set mask_in, which will be saved later, but ‘t’ is not modified, so this will not be sent to the TTY system.
Next we send the terminal settings, stored in local var ‘t’ to the TTY system
Tcsetattr(tt_ptr->fildes, TCSANOW, &t, status, save_errno, CHANGE_TERM_TRUE);
Next we save local mask_in and mask_term into global variables
temp_ptr->term_ctrl = mask_in;
memcpy(&temp_ptr->mask_term, &mask_term, SIZEOF(io_termmask));
Comment: We need to save state here ...
because resetterm() later needs to restore state set here.
resetterm() uses ttptr->ttio_struct as its source of TTY state
THEREFORE, t should be saved back into iod
Continuing, we get to iott_rdone (i.e. ‘read one’)
This calls setterm, checking ttPtr->setterm_done_by==0, indicating need.
setterm() called
This uses tt_ptr->canonical as the indicator of state. If FALSE (as set above) found, then code as follows. Here ‘t’ is a local variable.
t.c_lflag &= ~(ICANON | ECHO);
t.c_cc[VTIME] = 8;
t.c_cc[VMIN] = 1;
t.c_iflag &= ~(ICRNL);Set regardless of tt_ptr->canonical
Next we send ‘t’ to TTY system. NOTE: nothing here is saved in state of global var iod etc.
Tcsetattr(tt_ptr->fildes, TCSANOW, &t, status, save_errno, CHANGE_TERM_TRUE);
Next flag is set showing that setterm has been done.
tt_ptr->setterm_done_by = process_id;
COMMENT: We do not want to save the state here. Because settterm() is called by iott_rdone(), the TTY system is being just temporarily modified, with the idea being to restore this in resetterm().
Code for reading in 1 character from IO channel done next.
At the end of function, resetterm() is executed.
RESETTERM_IF_NEEDED(io_ptr, EXPECT_SETTERM_DONE_TRUE);
resetterm() called:
Local var ‘t’ is obtained from global var’s ttio_struct, and passed to TTY system
t = *ttptr->ttio_struct;
At runtime, this is binary 1000101000111011
bold bit means CANONICAL, at variance from last USE command
Tcsetattr(ttptr->fildes, TCSANOW, &t, status, save_errno, CHANGE_TERM_FALSE);
ttptr->setterm_done_by = 0; ← flag set to indicate setterm() will be needed again in the future.
Summary of how state of TTY system is apparently saved
*ttptr->ttio_struct This is the usual source of ‘t’. It is the raw data to send to TTY
Used in resetterm()
ttio_struct.c_lflag takes the following items
local mode flags (note: values below are OCTAL)
ISIG 0001 Enable signals.
ICANON 0002 Canonical input (erase and kill processing).
XCASE 0004
ECHO 0010 Enable echo.
ECHOE 0020 Echo erase char as err-correcting backspace
ECHOK 0040 Echo KILL.
ECHONL 0100 Echo NL.
NOFLSH 0200 Disable flush after interrupt or quit.
TOSTOP 0400 Send SIGTTOU for background output.
*ttptr->term_ctrl ← stores mask_in
NOTE: Several confusing similar terms exist and it is tricky to distinguish them.
mask, mask_in, ttptr->mask_term.mask[i]
NOTE: term_ctrl seems to be the place that SHOULD be holding the TTY state. I see many places in the code where it is modified and bit set, but I find only few places that it is used. It does seem to be the internal representation that yottadb uses to store the logical state, but it is NOT directly passed to the TTY system.
I see this → term_setup(term_ctrl); //found in io_init(), but I think this ‘term_ctrl’ is different. In term_setup(), this input param is called “ctrlc_enable”,and seems to be simple boolean.
term_ctrl is a bit flag, taking the following items
TRM_MODIFIERS 0
TRM_EDITMODE 1
TRM_NOTYPEAHD 2
TRM_READSYNC 4
TRM_PROMPT 8
TRM_PASTHRU 16
TRM_ESCTRMOVR 32
TRM_ESCAPE 64
TRM_NOECHO 128
TRM_CONVERT 256
**ttptr->canonical -- boolean to store if canonical
in setterm(), this variable is tested, and depending on values, c_cflag and c_cc are set
in iott_open(),iott_use() the value is set based on user parameters
in zshow_devices(), used to output zshow "D"
Changes made to fix issues -- See attached iott_use.c My changes are marked by //kt
iott_use() -- added:
*(temp_ptr->ttio_struct) = t; //save t (holding TTY settings) back into ttio_struct
I also modified these code blocks in iott_use(). I am setting flat in 't', so that it will be sent to the TTY system.
case iop_echo:
mask_in &= (~TRM_NOECHO);
t.c_lflag |= ECHO; //kt ADDED
break;
case iop_noecho:
mask_in |= TRM_NOECHO;
t.c_lflag &= (~ECHO); //kt ADDED
break;
Changing the IO function of yottadb is a really big issue. So I have been quite anxious and nervous about this. I have tried to consider any adverse consequences that might arise from these changes but can never anticipate every possible outcome. I would REALLY appreciate someone checking my work and giving me feedback.
Thanks
Kevin
--
You received this message because you are subscribed to the Google Groups "Everything MUMPS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to everythingmum...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/everythingmumps/352d0b04-6328-46aa-90ae-3f6ff0e22e54n%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Everything MUMPS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to everythingmum...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/everythingmumps/64da5add-31c0-4843-afce-51e9cee8dfaen%40googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/everythingmumps/fde23469-ddf6-4fe3-9e9e-f54730ce699an%40googlegroups.com.