diff -urN cui92/term.c cui93/term.c --- cui92/term.c Tue Apr 1 22:00:00 2014 +++ cui93/term.c Tue Apr 1 23:20:00 2014 @@ -12,6 +12,9 @@ #include #include #include +#include +#include +#include #ifdef __FreeBSD__ #include @@ -408,20 +411,80 @@ #define TIMEOUT_MSEC (3*1000) -static int +typedef struct trm_list *trm_list; + +struct trm_list{ + cui obj; + trm_list next; +}; + +static trm_list t_list = NULL; + +static void +trm_list_add(cui obj) +{ + trm_list p; + if((p = malloc(sizeof(struct trm_list))) == NULL) ERR("No Mem"); + p->obj = obj; + p->next = t_list; + t_list = p; +} + +static void +trm_list_del(cui obj) +{ + trm_list p = t_list, *prev = &t_list; + for(; p; prev=&p->next, p=p->next) if(p->obj == obj) break; + if(p == NULL) return; + *prev = p->next; + free(p); +} + +static void +sig_hdr(int sig) +{ + int pid; + trm_list p; + cui_terminal t; + + if(sig != SIGCHLD) return; + pid = wait(NULL); + for(p=t_list; p; p=p->next){ + t = (cui_terminal)p->obj; + if(t->pid == pid) break; + } + if(p == NULL) return; + t = (cui_terminal)p->obj; + cui_readable_del(p->obj, t->pipe_r); + trm_list_del(p->obj); +} + +static void boot_sh(cui obj) { + cui_terminal p = (cui_terminal)obj; int ret, master; + signal(SIGCHLD, sig_hdr); #if defined(__FreeBSD__) if((ret = forkpty(&master, NULL, NULL, NULL)) < 0) ERR("forkpy"); - if(ret != 0) return master; /* parent */ + if(ret != 0){ /* parent */ + p->pipe_r = p->pipe_w = master; + p->pid = ret; + trm_list_add(obj); + return; + } #else /* defined(__linux__) */ int slave; char *name; if((master = posix_openpt(O_RDWR)) < 0) ERR("posix_openpt"); if((ret = fork()) < 0) ERR("fork"); - if(ret != 0) return master; /* parent */ + if(ret != 0){ /* parent */ + p->pipe_r = p->pipe_w = master; + p->pid = ret; + trm_list_add(obj); + return; + } /* child */ setsid(); @@ -436,7 +499,6 @@ cui_dbg_close(); execl("/bin/sh", "/bin/sh", "-i", (char *)NULL); exit(0); - return 0; /* not reach */ } cui @@ -463,7 +525,7 @@ p->fill_r = cui_fill_new(obj, w-1, 0, 1, h-1, "|", CUI_ATTR_NORMAL); p->rszbox = cui_rszbox_new(obj); - p->pipe_r = p->pipe_w = boot_sh(obj); + boot_sh(obj); evts = CUI_EVT_DRAW|CUI_EVT_KEY|CUI_EVT_RESIZE|CUI_EVT_TIMER|CUI_EVT_READABLE; cui_bind(obj, evts, cui_terminal_hdr, NULL); @@ -527,7 +589,9 @@ return TRUE; case CUI_EVT_READABLE: - if((n = read(p->pipe_r, buf, 1024-1)) < 0) ERR("read"); + if((n = read(p->pipe_r, buf, 1024-1)) < 0){ + return TRUE; + } buf[n] = '\0'; cui_term_puts(p->term, buf); return TRUE; diff -urN cui92/term.h cui93/term.h --- cui92/term.h Tue Apr 1 22:00:00 2014 +++ cui93/term.h Tue Apr 1 23:20:00 2014 @@ -22,7 +22,7 @@ cui term, fill_l, fill_r, rszbox; int in_key_mode; int pipe_r, pipe_w; - + int pid; } *cui_terminal; cui cui_term_new(cui parent, int x, int y, int w, int h);