home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / jove / part06 / portsrv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-02  |  3.1 KB  |  158 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  3.  * provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is *
  5.  * included in all the files.                                           *
  6.  ************************************************************************/
  7.  
  8. /* This is a server for jove sub processes.  It runs the command and
  9.    signals jove when there is some output ready to send to jove. By the
  10.    time we get here, out standard output goes to jove's process input. */
  11.  
  12. #include "tune.h"
  13.  
  14. #ifdef PIPEPROCS    /* the whole file! */
  15.  
  16. #include "jove.h"
  17.  
  18. #include <signal.h>
  19. #include <sys/ioctl.h>
  20. #ifdef BSD4_2
  21. #   include <sys/wait.h>
  22. #else
  23. #   include <wait.h>
  24. #endif
  25.  
  26. struct header {
  27.     int    pid;
  28.     int    nbytes;
  29.     char    buf[512];
  30. } header;
  31.  
  32. #define HEADSIZE    ((sizeof header.pid) + sizeof (header.nbytes))
  33.  
  34. error(str)
  35. char    *str;
  36. {
  37.     header.pid = getpid();
  38.     header.nbytes = strlen(str);
  39.     strcpy(header.buf, str);
  40.     proc_write(&header, header.nbytes + 8);
  41.     exit(-2);
  42. }
  43.  
  44. int    ppid,
  45.     InputFD,
  46.     JovesInput;
  47.  
  48. p_inform()
  49. {
  50.     long    nbytes;
  51.  
  52.     ioctl(JovesInput, FIONREAD, (char *) &nbytes);
  53.     if (nbytes > 0)
  54.         kill(ppid, INPUT_SIG);
  55. }
  56.  
  57. proc_write(ptr, n)
  58. char    *ptr;
  59. {
  60.     long    nbytes;
  61.  
  62.     ioctl(1, FIONREAD, (char *) &nbytes);
  63.     
  64.     if (nbytes == 0)
  65.         kill(ppid, INPUT_SIG);
  66.  
  67.     (void) write(1, ptr, n);
  68.     alarm(1);
  69. }
  70.  
  71. read_pipe()
  72. {
  73.     register int    n;
  74.     
  75.     (void) signal(SIGALRM, p_inform);
  76.  
  77.     while ((header.nbytes = read(InputFD, header.buf, sizeof header.buf)) > 0) {
  78.         n = HEADSIZE + header.nbytes;
  79.         proc_write(&header, n);
  80.     }
  81. }
  82.  
  83. /* ARGSUSED */
  84. main(argc, argv)
  85. char    *argv[];
  86. {
  87.     int    p[2];
  88.     int    pid;
  89.  
  90.     if (pipe(p) == -1)
  91.         error("Cannot pipe jove portsrv.\n");
  92.  
  93.     ppid = getppid();
  94.     switch (pid = fork()) {
  95.     case -1:
  96.         error("portsrv: cannot fork.\n");
  97.  
  98.     case 0:
  99.         /* We'll intercept childs output in p[0] */
  100.         (void) dup2(p[1], 1);
  101.         (void) dup2(p[1], 2);
  102.         (void) close(p[0]);
  103.         (void) close(p[1]);
  104.             
  105.         (void) setpgrp(getpid(), getpid());
  106.         execv(argv[2], &argv[3]);
  107.         _exit(-4);
  108.  
  109.     default:
  110.         (void) close(0);
  111.                 /* Don't want this guy to read anything
  112.                    jove sends to our soon to be created
  113.                    child */
  114.  
  115.         JovesInput = atoi(argv[1]);
  116.         (void) signal(SIGINT, SIG_IGN);
  117.         (void) signal(SIGQUIT, SIG_IGN);
  118.         (void) close(p[1]);
  119.  
  120.         /* Tell jove the pid of the real child as opposed to us. */
  121.         header.pid = getpid();
  122.         header.nbytes = sizeof (int);
  123.         *(int *) header.buf = pid;
  124.         (void) write(1, (char *) &header, sizeof pid + HEADSIZE);
  125.         p_inform();    /* Inform jove */
  126.  
  127.         /* Read proc's output and send it to jove */
  128.         InputFD = p[0];
  129.         read_pipe();
  130.         (void) close(p[0]);
  131.         header.pid = getpid();
  132.         header.nbytes = EOF;    /* Tell jove we are finished */
  133.         (void) write(1, (char *) &header, HEADSIZE);
  134.         p_inform();
  135.         /* Try to exit like our child did ... */
  136.         {
  137.             union wait    w;
  138.  
  139. #ifndef VMUNIX
  140.             while (wait2(&w.w_status, 0) != pid)
  141. #else
  142.             while (wait3(&w.w_status, 0, 0) != pid)
  143. #endif
  144.                 ;
  145.             if (WIFEXITED(w))
  146.                 exit(w.w_retcode);
  147.             else if (WIFSIGNALED(w))
  148.                 kill(getpid(), w.w_termsig);
  149.         }
  150.     }
  151. }
  152.  
  153. #else PIPEPROCS
  154. main()
  155. {
  156. }
  157. #endif
  158.