From 9869785fa773671354496046ed0ad0ecb6b96afc Mon Sep 17 00:00:00 2001 From: Guenter Geiger Date: Tue, 6 Aug 2002 11:28:06 +0000 Subject: * call waitpid in clock callback, output return code of command * start of input pipe svn path=/trunk/externals/ggee/; revision=73 --- control/shell.c | 110 +++++++++++++++++++++++++++++++++++++++++++++---------- control/shell.pd | 25 +++++++++---- 2 files changed, 108 insertions(+), 27 deletions(-) (limited to 'control') diff --git a/control/shell.c b/control/shell.c index 79bd046..79d536b 100755 --- a/control/shell.c +++ b/control/shell.c @@ -29,23 +29,57 @@ typedef struct _shell int sr_intail; void* x_binbuf; int fdpipe[2]; + int fdinpipe[2]; int pid; + int x_del; + t_outlet* x_done; + t_clock* x_clock; } t_shell; static int shell_pid; -void child_handler(int n) + +void shell_cleanup(t_shell* x) +{ + sys_rmpollfn(x->fdpipe[0]); + + if (x->fdpipe[0]>0) close(x->fdpipe[0]); + if (x->fdpipe[1]>0) close(x->fdpipe[1]); + if (x->fdinpipe[0]>0) close(x->fdinpipe[0]); + if (x->fdinpipe[1]>0) close(x->fdinpipe[1]); + + x->fdpipe[0] = -1; + x->fdpipe[1] = -1; + x->fdinpipe[0] = -1; + x->fdinpipe[1] = -1; + clock_unset(x->x_clock); +} + +void shell_check(t_shell* x) { int ret; - waitpid(-1,&ret,WNOHANG); + int status; + ret = waitpid(x->pid,&status,WNOHANG); + if (ret == x->pid) { + shell_cleanup(x); + if (WIFEXITED(status)) { + outlet_float(x->x_done,WEXITSTATUS(status)); + } + else outlet_float(x->x_done,0); + } + else { + if (x->x_del < 100) x->x_del+=2; /* increment poll times */ + clock_delay(x->x_clock,x->x_del); + } } + void shell_bang(t_shell *x) { post("bang"); } -#if 1 +/* snippet from pd's code */ static void shell_doit(void *z, t_binbuf *b) { t_shell *x = (t_shell *)z; @@ -126,43 +160,78 @@ void shell_read(t_shell *x, int fd) binbuf_free(bbuf); } -#endif + +static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at) +{ + int i; + char tmp[MAXPDSTRING]; + int size = 0; + + if (x->fdinpipe[0] == -1) return; /* nothing to send to */ + + for (i=0;ifdinpipe[0],tmp); +} static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at) { int i; char* argv[20]; + t_symbol* sym; + + if (!strcmp(s->s_name,"send")) { + post("send"); + shell_send(x,s,ac,at); + return; + } argv[0] = s->s_name; - if (x->fdpipe[0] != -1) { - close(x->fdpipe[0]); - close(x->fdpipe[1]); - sys_rmpollfn(x->fdpipe[0]); - x->fdpipe[0] = -1; - x->fdpipe[1] = -1; + if (x->fdpipe[0] != -1) { + post("shell: old process still running"); kill(x->pid,SIGKILL); + shell_cleanup(x); } - - for (i=1;i<=ac;i++) { - argv[i] = atom_getsymbolarg(i-1,ac,at)->s_name; - /* post("argument %s",argv[i]); */ + if (pipe(x->fdpipe) < 0) { + error("unable to create pipe"); + return; + } + + if (pipe(x->fdinpipe) < 0) { + error("unable to create input pipe"); + return; } - argv[i] = 0; - if (pipe(x->fdpipe) < 0) - error("unable to create pipe"); sys_addpollfn(x->fdpipe[0],shell_read,x); if (!(x->pid = fork())) { + int status; + for (i=1;i<=ac;i++) { + argv[i] = getbytes(255); + atom_string(at,argv[i],255); +/* post("argument %s",argv[i]); */ + at++; + } + argv[i] = 0; + /* reassign stdout */ dup2(x->fdpipe[1],1); + dup2(x->fdinpipe[1],0); execvp(s->s_name,argv); - exit(0); + exit(-1); } + x->x_del = 1; + clock_delay(x->x_clock,x->x_del); if (x->x_echo) outlet_anything(x->x_obj.ob_outlet, s, ac, at); @@ -182,6 +251,8 @@ static void *shell_new() x->x_echo = 0; x->fdpipe[0] = -1; x->fdpipe[1] = -1; + x->fdinpipe[0] = -1; + x->fdinpipe[1] = -1; x->sr_inhead = x->sr_intail = 0; if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");; @@ -189,6 +260,8 @@ static void *shell_new() x->x_binbuf = binbuf_new(); outlet_new(&x->x_obj, &s_list); + x->x_done = outlet_new(&x->x_obj, &s_bang); + x->x_clock = clock_new(x, (t_method) shell_check); return (x); } @@ -198,7 +271,6 @@ void shell_setup(void) (t_method)shell_free,sizeof(t_shell), 0,0); class_addbang(shell_class,shell_bang); class_addanything(shell_class, shell_anything); - signal(SIGCHLD, child_handler); } diff --git a/control/shell.pd b/control/shell.pd index 194e10b..767559c 100755 --- a/control/shell.pd +++ b/control/shell.pd @@ -8,7 +8,6 @@ #X obj 330 107 shell; #X text 330 68 Getting the date; #X msg 118 17 bang; -#X msg 140 42 ./startwrapper; #X obj 60 17 metro 10; #X floatatom 271 89 4 0 0; #X obj 53 245 shell; @@ -16,15 +15,25 @@ #X msg 133 215 cvs commit -m fixed_bug_in_shell; #X msg 19 191 cvs -q update; #X obj 53 268 route ?; +#X msg 207 147 xedit; +#X obj 168 124 print done; +#X msg 215 257 send sadf asdf asdf; +#X msg 163 286 /usr/bin/perl; +#X msg 160 41 ./test; #X connect 0 0 2 0; +#X connect 0 1 17 0; #X connect 1 0 0 0; #X connect 3 0 0 0; #X connect 4 0 6 0; #X connect 6 0 5 0; -#X connect 8 0 10 0; -#X connect 9 0 0 0; -#X connect 10 0 3 0; -#X connect 12 0 16 0; -#X connect 14 0 12 0; -#X connect 15 0 12 0; -#X connect 16 1 13 0; +#X connect 8 0 9 0; +#X connect 9 0 3 0; +#X connect 10 0 11 0; +#X connect 11 0 15 0; +#X connect 13 0 11 0; +#X connect 14 0 11 0; +#X connect 15 1 12 0; +#X connect 16 0 11 0; +#X connect 18 0 11 0; +#X connect 19 0 11 0; +#X connect 20 0 0 0; -- cgit v1.2.1