diff -urN cui85/term.c cui86/term.c --- cui85/term.c Sun Mar 30 22:00:00 2014 +++ cui86/term.c Sun Mar 30 23:00:00 2014 @@ -1,3 +1,5 @@ +#define _XOPEN_SOURCE 600 + #include "term.h" #include "handler.h" #include "fill.h" @@ -9,6 +11,7 @@ #include #include #include +#include #define UPDATE_FLG (1<<7) @@ -384,34 +387,29 @@ #define TIMEOUT_MSEC (3*1000) -static void +static int boot_sh(cui obj) { - cui_terminal p = (cui_terminal)obj; - int pipe_to_sh[2], pipe_from_sh[2]; + int master, slave; int ret; + char *name; - if(pipe(pipe_to_sh) < 0) ERR("pipe"); - if(pipe(pipe_from_sh) < 0) ERR("pipe"); + if((master = posix_openpt(O_RDWR)) < 0) ERR("posix_openpt"); if((ret = fork()) < 0) ERR("fork"); - if(ret == 0){ /* child */ - setsid(); - close(pipe_to_sh[1]); - close(pipe_from_sh[0]); - dup2(pipe_to_sh[0] ,0); - dup2(pipe_from_sh[1] ,1); - dup2(pipe_from_sh[1] ,2); - close(pipe_to_sh[0]); - close(pipe_from_sh[1]); - - execl("/bin/sh", "/bin/sh", "-i", (char *)NULL); - exit(0); - } - /* parent */ - close(pipe_to_sh[0]); - close(pipe_from_sh[1]); - p->pipe_r = pipe_from_sh[0]; - p->pipe_w = pipe_to_sh[1]; + if(ret != 0) return master; /* parent */ + + /* child */ + setsid(); + if(grantpt(master) < 0) ERR("grantpt"); + if(unlockpt(master) < 0) ERR("unlockpt"); + if((name = ptsname(master)) == NULL) ERR("ptsname"); + if((slave = open(name, O_RDWR)) < 0) ERR("open"); + dup2(slave, 0); + dup2(slave, 1); + dup2(slave, 2); + execl("/bin/sh", "/bin/sh", "-i", (char *)NULL); + exit(0); + return 0; /* not reach */ } cui @@ -428,7 +426,6 @@ cui_terminal p = (cui_terminal)obj; int evts; - cui_dbg("cui_terminal_init\n"); cui_base_init(obj, parent, x, y, w, h); obj->flags |= CUI_FLG_CAN_FOCUS; @@ -439,8 +436,7 @@ p->fill_r = cui_fill_new(obj, w-1, 0, 1, h-1, "|", CUI_ATTR_NORMAL); p->rszbox = cui_rszbox_new(obj); - boot_sh(obj); - cui_dbg("pipr_r=%d , pipe_w=%d\n", p->pipe_r, p->pipe_w); + p->pipe_r = p->pipe_w = 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);