From 9a6954f9720784bc79668bcc6456f6a3f6a0c5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Haoran=20S=2E=20Diao=20=28=E5=88=81=E6=B5=A9=E7=84=B6=29?= <0@hairydiode.xyz> Date: Fri, 12 Sep 2025 22:33:39 -0700 Subject: Made it so pressing escape twice sends an escape to the IM, fixed the status line persisting even on exit. Refactored main process exit --- escape.h | 9 ++++++++- im.h | 7 ++++--- ptyim.c | 40 +++++++++++++++++++++++++--------------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/escape.h b/escape.h index 8b5f0dd..d7c54a4 100644 --- a/escape.h +++ b/escape.h @@ -31,6 +31,8 @@ enum esc_state { DECSC, DECRC, NORMAL, + //escape followed by an escape, has to be user generated + DOUBLE_ESC, }; //global stdin -> pty ESC state enum esc_state in_state = NORMAL; @@ -54,6 +56,7 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat case C1: case DECSC: case DECRC: + case DOUBLE_ESC: //all the sequences that have ended don't have an end //and default to normal case NORMAL: @@ -91,8 +94,12 @@ enum esc_state update_esc_state(char * buff,unsigned int buff_len, enum esc_stat } else if (c == '8') { state = DECSC; + } + else if (c == 0x1B) { + state = DOUBLE_ESC; //deformed escape sequence - } else { + } + else { state = NORMAL; } break; diff --git a/im.h b/im.h index d92191c..47ae538 100644 --- a/im.h +++ b/im.h @@ -16,10 +16,10 @@ //the one you desire #define BACKSPACE_KEY 0x7F #define BACKSPACE_KEY_2 0x08 -//setting it to the actual escape character interferes with arrow keys and -//whatnot -//#define ESCAPE_KEY 0x1B +//the literal escape char is only fed into the im if it is pressed twice, see +//escape.h #define ESCAPE_KEY '`' +#define ESCAPE_KEY_2 0x1B //Vertical Tab Ctrl+K #define TOGGLE_KEY 0x0B #define IM_KEY_RANGE_LEN 3 @@ -146,6 +146,7 @@ int update_im_state(char input, char * output) { if (im_buffer_pos > 0) { switch (input) { //escape, cancels + case ESCAPE_KEY_2: case ESCAPE_KEY: clear_im_buffer(); return 0; diff --git a/ptyim.c b/ptyim.c index 34fdbec..eedffd3 100644 --- a/ptyim.c +++ b/ptyim.c @@ -16,12 +16,6 @@ #define WRITE_BUFFER_LEN 128 //determines if the master process is running int running = 1; -//hook for when the pty child process dies -void childhook(int a) { - running = 0; - //this way it exists even if the loop is waiting for 1 last read char - _exit(0); -} //pty master and slave fd int pty_slave = -1; int pty_master = -1; @@ -45,6 +39,9 @@ void winchhook(int a) { ioctl(pty_slave, TIOCSWINSZ, &sz); } +//child process pids +pid_t shell_pid; +pid_t om_pid; //return 0 on success, -1 on error //sets the global vars pty_master and pty_slave int make_pty() { @@ -88,6 +85,24 @@ void condition_stdin() { void restore_stdin() { tcsetattr(STDIN_FILENO,TCSANOW,&stdin_termio_bk); } +//main thread exit +void exit_main() { + //kill shell , can not be blocked + kill(shell_pid, SIGKILL); + //exit, only the master process should reach this point + close(pty_master); + close(pty_slave); + restore_stdin(); + //clears the screen so the im statusline goes away + write(STDIN_FILENO,"\033[2J", 4); + _exit(0); +} +//hook for when the pty child process dies +void childhook(int a) { + running = 0; + //this way it exists even if the loop is waiting for 1 last read char + exit_main(); +} int main (int argc, char * argv[], char * envp[]) { condition_stdin(); if (make_pty() != 0) { @@ -98,7 +113,7 @@ int main (int argc, char * argv[], char * envp[]) { //resize interrupt handler winchhook(0); //forks for running bash - pid_t shell_pid = fork(); + shell_pid = fork(); if (shell_pid == 0) { //shell child process //set self to be session leader @@ -137,7 +152,7 @@ int main (int argc, char * argv[], char * envp[]) { } else { //forks for read and write, master process handles im, child //process just handles transfering pty output to stdout - pid_t om_pid = fork(); + om_pid = fork(); if (om_pid == 0) { //sets the name for cleaner ps output prctl(PR_SET_NAME, "ptyim om thread"); @@ -179,7 +194,7 @@ int main (int argc, char * argv[], char * envp[]) { fprintf(stderr, "%c: %d\n", read_buffer[0],in_state); //skips if the char was anything but //normal - if (in_state == NORMAL) { + if (in_state == NORMAL || in_state ==DOUBLE_ESC) { //feeds the input char into the im state machine char input_buffer[IM_TABLE_ENTRY_LEN+1] = {0}; int im_chars = update_im_state(read_buffer[0], @@ -203,11 +218,6 @@ int main (int argc, char * argv[], char * envp[]) { kill(om_pid, SIGKILL); } } - //kill shell , can not be blocked - kill(shell_pid, SIGKILL); - //exit, only the master process should reach this point - close(pty_master); - close(pty_slave); - restore_stdin(); + exit_main(); return 0; } -- cgit v1.1