aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuenter Geiger <ggeiger@users.sourceforge.net>2002-08-06 11:28:06 +0000
committerGuenter Geiger <ggeiger@users.sourceforge.net>2002-08-06 11:28:06 +0000
commit9869785fa773671354496046ed0ad0ecb6b96afc (patch)
tree2f2b9a2a7831ea7545021647e034d8a892495c10
parent6f40d0bd05bce901318a24e6c1409a6995a26935 (diff)
* call waitpid in clock callback, output return code of command
* start of input pipe svn path=/trunk/externals/ggee/; revision=73
-rwxr-xr-xcontrol/shell.c110
-rwxr-xr-xcontrol/shell.pd25
2 files changed, 108 insertions, 27 deletions
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;i<ac;i++) {
+ atom_string(at,tmp+size,MAXPDSTRING - size);
+ at++;
+ size=strlen(tmp);
+ tmp[size++] = ' ';
+ }
+ tmp[size-1] = '\0';
+ post("sending %s",tmp);
+ fprintf(x->fdinpipe[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;