summaryrefslogtreecommitdiff
path: root/ptyim.c
diff options
context:
space:
mode:
authorHaoran S. Diao (刁浩然) <0@hairydiode.xyz>2025-09-12 01:40:31 -0700
committerHaoran S. Diao (刁浩然) <0@hairydiode.xyz>2025-09-12 01:40:31 -0700
commit5dc971ab6211946f8245dbaaa280aa0c8287e7b0 (patch)
treebfebd5a895e3b032a06372876e1c0812ed92d0d9 /ptyim.c
parent97222aef122ab2792bce053654e7e27755140d9a (diff)
Made ptty -> stdout be on a seperate thread to we can make stdin/stdout blocking
again for performance reasons
Diffstat (limited to 'ptyim.c')
-rw-r--r--ptyim.c93
1 files changed, 55 insertions, 38 deletions
diff --git a/ptyim.c b/ptyim.c
index bf84ec7..daf64b7 100644
--- a/ptyim.c
+++ b/ptyim.c
@@ -98,9 +98,9 @@ int main (int argc, char * argv[], char * envp[]) {
//resize interrupt handler
winchhook(0);
//forks for running bash
- pid_t mypid = fork();
- if (mypid == 0) {
- //child process
+ pid_t shell_pid = fork();
+ if (shell_pid == 0) {
+ //shell child process
//set self to be session leader
if (setsid() <0) {
fprintf(stderr, "failed to make new session\n");
@@ -135,47 +135,64 @@ int main (int argc, char * argv[], char * envp[]) {
//should automatically close any file descriptors
_exit(0);
} else {
- //master process
- //registers interrupts
- signal(SIGCHLD, childhook);
- signal(SIGWINCH, winchhook);
- //display the im for the first time
- disp_im(STDIN_FILENO, trows, tcols);
+ //forks for read and write, master process handles im, child
+ //process just handles transfering pty output to stdout
+ pid_t om_pid = fork();
+ if (om_pid == 0) {
+ //output manager child process
+ //runs forever until SIGKILL'd
+ while (true) {
+ //output manager child process
+ //buffer for reading from pty_master and writing to stdout
+ char write_buffer[WRITE_BUFFER_LEN] = {0};
+ //only read/write syscalls work well for this, printfs
+ //etcs do not work
+ // pty_master -> STDOUT
+ int wchars_read = read(pty_master,write_buffer, WRITE_BUFFER_LEN);
+ if (wchars_read >0) {
+ write(STDOUT_FILENO,write_buffer,wchars_read);
+ }
+ // stdin -> pty_master, im logic is also here
+ }
+ //child process exit
+ _exit(0);
+ } else {
+ //master process
+ //registers interrupts
+ signal(SIGCHLD, childhook);
+ signal(SIGWINCH, winchhook);
+ //display the im for the first time
+ disp_im(STDIN_FILENO, trows, tcols);
- //1 char buffer for reading from stdin and writing to pty_master
- char read_buffer[1] = {0};
+ //1 char buffer for reading from stdin and writing to pty_master
+ char read_buffer[1] = {0};
- //buffer for reading from pty_master and writing to stdout
- char write_buffer[WRITE_BUFFER_LEN] = {0};
- //open
- while (running) {
- //only read/write syscalls work well for this, printfs
- //etcs do not work
- // pty_master -> STDOUT
- int wchars_read = read(pty_master,write_buffer, WRITE_BUFFER_LEN);
- if (wchars_read >0) {
- write(STDOUT_FILENO,write_buffer,wchars_read);
- }
- // stdin -> pty_master, im logic is also here
- int rchars_read = read(STDIN_FILENO, read_buffer, 1);
- if (rchars_read > 0) {
- //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],
- input_buffer);
- //just in case it wasn't null terminated right
- input_buffer[im_chars] = 0;
- if (im_chars >0) {
- //writes the input into pty_master if
- //there was an output from the state
- //machine
- write(pty_master,input_buffer,im_chars);
+ //open
+ while (running) {
+ int rchars_read = read(STDIN_FILENO, read_buffer, 1);
+ if (rchars_read > 0) {
+ //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],
+ input_buffer);
+ //just in case it wasn't null terminated right
+ input_buffer[im_chars] = 0;
+ if (im_chars >0) {
+ //writes the input into pty_master if
+ //there was an output from the state
+ //machine
+ write(pty_master,input_buffer,im_chars);
+ }
+ //any input update will lead to a disp_im update
+ disp_im(STDIN_FILENO, trows, tcols);
}
- //any input update will lead to a disp_im update
- disp_im(STDIN_FILENO, trows, tcols);
}
+ //at the end of the main process, kil lthe om process
+ 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);