Author Topic: Non-canonical input without echo  (Read 6454 times)

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Non-canonical input without echo
« on: June 06, 2012, 04:47:20 AM »
Excerpt from Frank's June 28, 2011 on subject

Code: [Select]
   struc termios
alignb 4
.c_iflag: resd 1 ; input mode flags
.c_oflag: resd 1 ; output mode flags
.c_cflag: resd 1 ; control mode flags
.c_lflag: resd 1 ; local mode flags
.c_line: resb 1 ; line discipline
.c_cc: resb 19 ; control characters
    endstruc

Which is 36 bytes in length.  From same thread

Code: [Select]
   mov eax, SYS_IOCTL        ; get current mode
    mov ebx, STDIN
    mov ecx, TCGETS
    lea edx, [ebp - termios_size]
    int 80h

and my 64 bit version

Code: [Select]
                xor     rax, rax
                mov     rdi, rax
                mov     rdi, SYS_READ
                mov     rsi, rax
                mov     esi, TCGETS
                mov     rdx, rsp
                mov      al, SYS_IOCTL
                syscall
 

and I have in fact verified that even in 64 bit mode versus int80, 36 bytes of stack where populated with data.

This little tidbit though, extracted from /usr/include/x86_64/bits/termios.h tells a very different story in so much as this structure is 60 bytes. 

Code: [Select]
#include <iostream>

using namespace std;


typedef unsigned char cc_t;
typedef unsigned int speed_t;
typedef unsigned int tcflag_t;

#define NCCS 32
struct termios
  {
    tcflag_t c_iflag; /* input mode flags */
    tcflag_t c_oflag; /* output mode flags */
    tcflag_t c_cflag; /* control mode flags */
    tcflag_t c_lflag; /* local mode flags */
    cc_t c_line; /* line discipline */
    cc_t c_cc[NCCS]; /* control characters */
    speed_t c_ispeed; /* input speed */
    speed_t c_ospeed; /* output speed */
  };
 
int main () {
        cout << sizeof (termios) << endl;
        return 0;
        }

My question is, am I going to be ok doing it with syscall and logically assuming for backward compatibility the structure is 36 bytes


Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Non-canonical input without echo
« Reply #1 on: June 06, 2012, 05:49:05 AM »
Dunno. I'd go with what it says in termios.h to be on the safe side, I think. I vaguely recall some doubt about 19 bytes for "c_cc".

You will notice (probably) that I used only one copy of the structure, ASSuming that the original configuration was "as expected". Safer to use two copies of the structure, "get" to one, copy it to another and tweak the bits we need, "set" it to our new configuration, then "set" it back to the original when finished.

Also, if I "suspend" the app with cntl-'d' and restore it back with "fg", we're back in the situation where sys_read won't return without "enter". Only happens for the first key. I think the same thing happens with SIG-WINCH. We should probably "catch" (at least) those two signals. I don't know how to do that...

The "usual" way to do this involves setting it and leaving it there for the duration of the app, rather than setting it back and forth for each key. I wanted to be able to use sys_read "as usual" between "get just one key" uses. I wonder if it would be possible to make a "copy" (dup?) of stdin and set that, leaving the original stdin alone? Don't know how to do that, either.

My method "usually works", but I think it needs more work to be "right". Looking forward to what you come up with...

Best,
Frank


Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Non-canonical input without echo
« Reply #2 on: June 06, 2012, 02:26:46 PM »
Your structure is consistent with what TCGETS & SYS_IOCTL returns, so that's what I'm going to fly with. What I'm going to do is just a little different;
  • Read default parameters on invocation of application
  • Allow functionality to be turned off and on in Input, Output & Control
  • Settings will remain until next change or call to reset defaults

I will post results in Code Examples