diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/extra/shell.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/extra/shell.c | 314 |
1 files changed, 1 insertions, 313 deletions
diff --git a/apps/plugins/pdbox/PDa/extra/shell.c b/apps/plugins/pdbox/PDa/extra/shell.c index a0b6cef5b5..dd6b0e239d 100644 --- a/apps/plugins/pdbox/PDa/extra/shell.c +++ b/apps/plugins/pdbox/PDa/extra/shell.c | |||
@@ -309,316 +309,4 @@ void shell_setup(void) | |||
309 | class_addanything(shell_class, shell_anything); | 309 | class_addanything(shell_class, shell_anything); |
310 | } | 310 | } |
311 | 311 | ||
312 | 312 | ||
313 | /* (C) Guenter Geiger <geiger@epy.co.at> */ | ||
314 | |||
315 | #include "m_pd.h" | ||
316 | #ifdef NT | ||
317 | #pragma warning( disable : 4244 ) | ||
318 | #pragma warning( disable : 4305 ) | ||
319 | #endif | ||
320 | |||
321 | #include <unistd.h> | ||
322 | #include <stdlib.h> | ||
323 | #include <string.h> | ||
324 | #include <stdio.h> | ||
325 | #include <sys/types.h> | ||
326 | #include <sys/wait.h> | ||
327 | #include <signal.h> | ||
328 | #include <sched.h> | ||
329 | |||
330 | void sys_rmpollfn(int fd); | ||
331 | void sys_addpollfn(int fd, void* fn, void *ptr); | ||
332 | |||
333 | /* ------------------------ shell ----------------------------- */ | ||
334 | |||
335 | #define INBUFSIZE 1024 | ||
336 | |||
337 | static t_class *shell_class; | ||
338 | |||
339 | |||
340 | static void drop_priority(void) | ||
341 | { | ||
342 | #ifdef _POSIX_PRIORITY_SCHEDULING | ||
343 | struct sched_param par; | ||
344 | int p1 ,p2, p3; | ||
345 | par.sched_priority = 0; | ||
346 | sched_setscheduler(0,SCHED_OTHER,&par); | ||
347 | #endif | ||
348 | } | ||
349 | |||
350 | |||
351 | typedef struct _shell | ||
352 | { | ||
353 | t_object x_obj; | ||
354 | int x_echo; | ||
355 | char *sr_inbuf; | ||
356 | int sr_inhead; | ||
357 | int sr_intail; | ||
358 | void* x_binbuf; | ||
359 | int fdpipe[2]; | ||
360 | int fdinpipe[2]; | ||
361 | int pid; | ||
362 | int x_del; | ||
363 | t_outlet* x_done; | ||
364 | t_clock* x_clock; | ||
365 | } t_shell; | ||
366 | |||
367 | static int shell_pid; | ||
368 | |||
369 | |||
370 | void shell_cleanup(t_shell* x) | ||
371 | { | ||
372 | sys_rmpollfn(x->fdpipe[0]); | ||
373 | |||
374 | if (x->fdpipe[0]>0) close(x->fdpipe[0]); | ||
375 | if (x->fdpipe[1]>0) close(x->fdpipe[1]); | ||
376 | if (x->fdinpipe[0]>0) close(x->fdinpipe[0]); | ||
377 | if (x->fdinpipe[1]>0) close(x->fdinpipe[1]); | ||
378 | |||
379 | x->fdpipe[0] = -1; | ||
380 | x->fdpipe[1] = -1; | ||
381 | x->fdinpipe[0] = -1; | ||
382 | x->fdinpipe[1] = -1; | ||
383 | clock_unset(x->x_clock); | ||
384 | } | ||
385 | |||
386 | void shell_check(t_shell* x) | ||
387 | { | ||
388 | int ret; | ||
389 | int status; | ||
390 | ret = waitpid(x->pid,&status,WNOHANG); | ||
391 | if (ret == x->pid) { | ||
392 | shell_cleanup(x); | ||
393 | if (WIFEXITED(status)) { | ||
394 | outlet_float(x->x_done,WEXITSTATUS(status)); | ||
395 | } | ||
396 | else outlet_float(x->x_done,0); | ||
397 | } | ||
398 | else { | ||
399 | if (x->x_del < 100) x->x_del+=2; /* increment poll times */ | ||
400 | clock_delay(x->x_clock,x->x_del); | ||
401 | } | ||
402 | } | ||
403 | |||
404 | |||
405 | void shell_bang(t_shell *x) | ||
406 | { | ||
407 | post("bang"); | ||
408 | } | ||
409 | |||
410 | /* snippet from pd's code */ | ||
411 | static void shell_doit(void *z, t_binbuf *b) | ||
412 | { | ||
413 | t_shell *x = (t_shell *)z; | ||
414 | int msg, natom = binbuf_getnatom(b); | ||
415 | t_atom *at = binbuf_getvec(b); | ||
416 | |||
417 | for (msg = 0; msg < natom;) | ||
418 | { | ||
419 | int emsg; | ||
420 | for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA | ||
421 | && at[emsg].a_type != A_SEMI; emsg++) | ||
422 | ; | ||
423 | if (emsg > msg) | ||
424 | { | ||
425 | int i; | ||
426 | for (i = msg; i < emsg; i++) | ||
427 | if (at[i].a_type == A_DOLLAR || at[i].a_type == A_DOLLSYM) | ||
428 | { | ||
429 | pd_error(x, "netreceive: got dollar sign in message"); | ||
430 | goto nodice; | ||
431 | } | ||
432 | if (at[msg].a_type == A_FLOAT) | ||
433 | { | ||
434 | if (emsg > msg + 1) | ||
435 | outlet_list(x->x_obj.ob_outlet, 0, emsg-msg, at + msg); | ||
436 | else outlet_float(x->x_obj.ob_outlet, at[msg].a_w.w_float); | ||
437 | } | ||
438 | else if (at[msg].a_type == A_SYMBOL) | ||
439 | outlet_anything(x->x_obj.ob_outlet, at[msg].a_w.w_symbol, | ||
440 | emsg-msg-1, at + msg + 1); | ||
441 | } | ||
442 | nodice: | ||
443 | msg = emsg + 1; | ||
444 | } | ||
445 | } | ||
446 | |||
447 | |||
448 | void shell_read(t_shell *x, int fd) | ||
449 | { | ||
450 | char buf[INBUFSIZE]; | ||
451 | t_binbuf* bbuf = binbuf_new(); | ||
452 | int i; | ||
453 | int readto = | ||
454 | (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); | ||
455 | int ret; | ||
456 | |||
457 | ret = read(fd, buf,INBUFSIZE-1); | ||
458 | buf[ret] = '\0'; | ||
459 | |||
460 | for (i=0;i<ret;i++) | ||
461 | if (buf[i] == '\n') buf[i] = ';'; | ||
462 | if (ret < 0) | ||
463 | { | ||
464 | error("shell: pipe read error"); | ||
465 | sys_rmpollfn(fd); | ||
466 | x->fdpipe[0] = -1; | ||
467 | close(fd); | ||
468 | return; | ||
469 | } | ||
470 | else if (ret == 0) | ||
471 | { | ||
472 | post("EOF on socket %d\n", fd); | ||
473 | sys_rmpollfn(fd); | ||
474 | x->fdpipe[0] = -1; | ||
475 | close(fd); | ||
476 | return; | ||
477 | } | ||
478 | else | ||
479 | { | ||
480 | int natom; | ||
481 | t_atom *at; | ||
482 | binbuf_text(bbuf, buf, strlen(buf)); | ||
483 | |||
484 | natom = binbuf_getnatom(bbuf); | ||
485 | at = binbuf_getvec(bbuf); | ||
486 | shell_doit(x,bbuf); | ||
487 | } | ||
488 | binbuf_free(bbuf); | ||
489 | } | ||
490 | |||
491 | |||
492 | static void shell_send(t_shell *x, t_symbol *s,int ac, t_atom *at) | ||
493 | { | ||
494 | int i; | ||
495 | char tmp[MAXPDSTRING]; | ||
496 | int size = 0; | ||
497 | |||
498 | if (x->fdinpipe[0] == -1) return; /* nothing to send to */ | ||
499 | |||
500 | for (i=0;i<ac;i++) { | ||
501 | atom_string(at,tmp+size,MAXPDSTRING - size); | ||
502 | at++; | ||
503 | size=strlen(tmp); | ||
504 | tmp[size++] = ' '; | ||
505 | } | ||
506 | tmp[size-1] = '\0'; | ||
507 | post("sending %s",tmp); | ||
508 | write(x->fdinpipe[0],tmp,strlen(tmp)); | ||
509 | } | ||
510 | |||
511 | static void shell_anything(t_shell *x, t_symbol *s, int ac, t_atom *at) | ||
512 | { | ||
513 | int i; | ||
514 | char* argv[20]; | ||
515 | t_symbol* sym; | ||
516 | |||
517 | if (!strcmp(s->s_name,"send")) { | ||
518 | post("send"); | ||
519 | shell_send(x,s,ac,at); | ||
520 | return; | ||
521 | } | ||
522 | |||
523 | argv[0] = s->s_name; | ||
524 | |||
525 | if (x->fdpipe[0] != -1) { | ||
526 | post("shell: old process still running"); | ||
527 | kill(x->pid,SIGKILL); | ||
528 | shell_cleanup(x); | ||
529 | } | ||
530 | |||
531 | |||
532 | if (pipe(x->fdpipe) < 0) { | ||
533 | error("unable to create pipe"); | ||
534 | return; | ||
535 | } | ||
536 | |||
537 | if (pipe(x->fdinpipe) < 0) { | ||
538 | error("unable to create input pipe"); | ||
539 | return; | ||
540 | } | ||
541 | |||
542 | |||
543 | sys_addpollfn(x->fdpipe[0],shell_read,x); | ||
544 | |||
545 | if (!(x->pid = fork())) { | ||
546 | int status; | ||
547 | char* cmd = getbytes(1024); | ||
548 | char* tcmd = getbytes(1024); | ||
549 | strcpy(cmd,s->s_name); | ||
550 | |||
551 | #if 0 | ||
552 | for (i=1;i<=ac;i++) { | ||
553 | argv[i] = getbytes(255); | ||
554 | atom_string(at,argv[i],255); | ||
555 | /* post("argument %s",argv[i]); */ | ||
556 | at++; | ||
557 | } | ||
558 | argv[i] = 0; | ||
559 | #endif | ||
560 | for (i=1;i<=ac;i++) { | ||
561 | atom_string(at,tcmd,255); | ||
562 | strcat(cmd," "); | ||
563 | strcat(cmd,tcmd); | ||
564 | at++; | ||
565 | } | ||
566 | |||
567 | |||
568 | /* reassign stdout */ | ||
569 | dup2(x->fdpipe[1],1); | ||
570 | dup2(x->fdinpipe[1],0); | ||
571 | |||
572 | /* drop privileges */ | ||
573 | drop_priority(); | ||
574 | seteuid(getuid()); /* lose setuid priveliges */ | ||
575 | |||
576 | post("executing %s",cmd); | ||
577 | system(cmd); | ||
578 | // execvp(s->s_name,argv); | ||
579 | exit(0); | ||
580 | } | ||
581 | x->x_del = 4; | ||
582 | clock_delay(x->x_clock,x->x_del); | ||
583 | |||
584 | if (x->x_echo) | ||
585 | outlet_anything(x->x_obj.ob_outlet, s, ac, at); | ||
586 | } | ||
587 | |||
588 | |||
589 | |||
590 | void shell_free(t_shell* x) | ||
591 | { | ||
592 | binbuf_free(x->x_binbuf); | ||
593 | } | ||
594 | |||
595 | static void *shell_new(void) | ||
596 | { | ||
597 | t_shell *x = (t_shell *)pd_new(shell_class); | ||
598 | |||
599 | x->x_echo = 0; | ||
600 | x->fdpipe[0] = -1; | ||
601 | x->fdpipe[1] = -1; | ||
602 | x->fdinpipe[0] = -1; | ||
603 | x->fdinpipe[1] = -1; | ||
604 | |||
605 | x->sr_inhead = x->sr_intail = 0; | ||
606 | if (!(x->sr_inbuf = (char*) malloc(INBUFSIZE))) bug("t_shell");; | ||
607 | |||
608 | x->x_binbuf = binbuf_new(); | ||
609 | |||
610 | outlet_new(&x->x_obj, &s_list); | ||
611 | x->x_done = outlet_new(&x->x_obj, &s_bang); | ||
612 | x->x_clock = clock_new(x, (t_method) shell_check); | ||
613 | return (x); | ||
614 | } | ||
615 | |||
616 | void shell_setup(void) | ||
617 | { | ||
618 | shell_class = class_new(gensym("shell"), (t_newmethod)shell_new, | ||
619 | (t_method)shell_free,sizeof(t_shell), 0,0); | ||
620 | class_addbang(shell_class,shell_bang); | ||
621 | class_addanything(shell_class, shell_anything); | ||
622 | } | ||
623 | |||
624 | |||