casciitext-editortermioscontrol-characters

Return control character as number


so I'm trying to print every keypress as an integer and character referencing to ASCII code. and it seems I can't print some of control character.

After reading antirez's booklet about his kilo text editor I managed to disable ctrl + c, z, s, q. all those will print 3 26 19 17 respectively. But I can't seem to disable ctrl + v which by his guide I'm supposed to turning off IEXTEN as in the code below. my ctrl + v seems to return whatever in my clipboard when it's supposed to return 22.

void enableRawMode(){
    tcgetattr(STDIN_FILENO, &orig_termios);
    atexit(disableRawMode);

    struct termios raw = orig_termios;
    
    tcgetattr(STDIN_FILENO, &raw);
    
    raw.c_iflag &= ~( ICRNL | IXON );
    raw.c_lflag &= ~( ECHO | ICANON | IEXTEN | ISIG );

    tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
}

int main(){
    enableRawMode();

    char c;
    while (read(STDIN_FILENO, &c, 1) == 1 && c != 'q'){
        if (iscntrl(c)){
            printf("%d\n", c);
        }
        else{
            printf("%d ('%c')\n", c, c);
        }
    }
    return 0;
}

Anyone know why this happen? any alternative solution? I ran this on WSL terminal, does it have something to do with that?


Solution

  •                 Possibly                                Machine
                    another                                 executing
                    machine                                 your program
    +------------------------------------+    +------------------------------------+
    |  +------------+    +------------+  |    |  +------------+    +------------+  |
    |  |            |    | Terminal   |  |    |  | Virtual    |    |            |  |
    |  | User       |    | program    |  |    |  | terminal   |    | Your       |  |
    |  |            |<-->|            |<-|----|->| device.    |<-->| program    |  |
    |  |            |    | e.g. PuTTY |  |    |  | Part of OS |    |            |  |
    |  +------------+    +------------+  |    |  +------------+    +------------+  |
    +------------------------------------+    +------------------------------------+
    

    (This is greatly simplified, and it's just the model that's relevant to the presented scenario.)

    tcsetattr controls the terminal device.

    But it has no effect on the program taking input from the user, which might not even be on the same machine.

    Take Ctrl-C for example. The terminal program will normally send this to the other machine. The terminal device might send a SIGINT when it receives the Ctrl-C. Or it might send it raw. This you can control tcsetattr.

    But Ctrl-V is different. It's the terminal program that is handling the Ctrl-V in your case. The terminal device used by your program doesn't get to see it. So this isn't something you can control tcsetattr. At best, you can alter the settings of the terminal program manually.