home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / jove-4.16-src.tgz / tar.out / bsd / jove / portsrv.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  207 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986-1996 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 program is invoked by JOVE for two purposes related to PIPEPROCS:
  9.  * - "kbd": gather tty input into lumps and send them to JOVE proper.
  10.  * - "portsrv": gather process output into lumps and send them to JOVE
  11.  * These functions are gathered into one program to reduce the number
  12.  * of misc. programs to install.  The resulting program is small anyway.
  13.  */
  14.  
  15. #include "jove.h"
  16.  
  17. #ifdef PIPEPROCS    /* almost the whole file! */
  18.  
  19. #include <signal.h>
  20. #include <errno.h>
  21.  
  22. #include "sysprocs.h"
  23. #include "iproc.h"
  24.  
  25. private struct lump    lump;
  26.  
  27. /* JOVE sends KBDSIG whenever it wants the kbd process (this program)
  28.    to stop competing for input from the keyboard.  JOVE does this when
  29.    JOVE realizes that there are no more interactive processes running.
  30.    The reason we go through all this trouble is that JOVE slows down
  31.    a lot when it's getting its keyboard input via a pipe. */
  32.  
  33. private SIGRESTYPE strt_read proto((int));
  34.  
  35. private SIGRESTYPE
  36. hold_read(junk)
  37. int    junk;    /* passed in when invoked by a signal; of no interest */
  38. {
  39.     signal(KBDSIG, strt_read);
  40.     pause();
  41.     return SIGRESVALUE;
  42. }
  43.  
  44. private SIGRESTYPE
  45. strt_read(junk)
  46. int    junk;
  47. {
  48.     signal(KBDSIG, hold_read);
  49.     return SIGRESVALUE;
  50. }
  51.  
  52. private void
  53. kbd_process()
  54. {
  55.     int    pid,
  56.         n;
  57.  
  58.     signal(SIGINT, SIG_IGN);
  59.     pid = getpid();
  60.     lump.header.pid = pid;
  61.  
  62.     strt_read(0);
  63.     for (;;) {
  64.         n = read(0, (UnivPtr) lump.data, sizeof(lump.data));
  65.         if (n == -1) {
  66.             if (errno != EINTR)
  67.                 break;
  68.             continue;
  69.         }
  70.         lump.header.nbytes = n;
  71.         /* It is not clear what we can do if this write fails */
  72.         do ; while (write(1, (UnivPtr) &lump, sizeof(struct header) + n) < 0
  73.             && errno == EINTR);
  74.     }
  75. }
  76.  
  77. /* This is a server for jove sub processes.  By the time we get here, our
  78.    standard output goes to jove's process input. */
  79.  
  80. private int    tty_fd;
  81.  
  82. private void
  83. proc_write(ptr, n)
  84. UnivConstPtr    ptr;
  85. size_t    n;
  86. {
  87.     /* It is not clear what we can do if this write fails */
  88.     do ; while (write(1, ptr, n) < 0 && errno == EINTR);
  89. }
  90.  
  91. private void
  92. read_pipe(fd)
  93. int    fd;
  94. {
  95.     register size_t    n;
  96.  
  97.     while ((lump.header.nbytes = read(fd, (UnivPtr) lump.data, sizeof lump.data)) > 0) {
  98.         n = sizeof(struct header) + lump.header.nbytes;
  99.         proc_write((UnivConstPtr) &lump, n);
  100.     }
  101. }
  102.  
  103. private void
  104. proc_error(str)
  105. char    *str;
  106. {
  107.     lump.header.pid = getpid();
  108.     lump.header.nbytes = strlen(str);
  109.     strcpy(lump.data, str);
  110.     proc_write((UnivConstPtr) &lump, sizeof(struct header) + lump.header.nbytes);
  111.     /* It is not clear what we can do if this write fails */
  112.     do ; while (write(tty_fd, (UnivConstPtr)str, strlen(str)) < 0 && errno == EINTR);
  113.     exit(-2);
  114. }
  115.  
  116. private void
  117. portsrv_process(argc, argv)
  118. int    argc;
  119. char    **argv;
  120. {
  121.     int    p[2];
  122.     pid_t    pid;
  123.  
  124.     if (pipe(p) == -1)
  125.         proc_error("Cannot pipe jove portsrv.\n");
  126.  
  127.     switch (pid = fork()) {
  128.     case -1:
  129.         proc_error("portsrv: cannot fork.\n");
  130.         /*NOTREACHED*/
  131.  
  132.     case 0:
  133.         /* We'll intercept child's output in p[0] */
  134.         (void) dup2(p[1], 1);
  135.         (void) dup2(p[1], 2);
  136.         (void) close(p[0]);
  137.         (void) close(p[1]);
  138.  
  139.         NEWPG();
  140.         execv(argv[1], &argv[2]);
  141.         _exit(-4);
  142.         /*NOTREACHED*/
  143.  
  144.     default:
  145.         (void) close(0);
  146.         tty_fd = open("/dev/tty", 1);
  147.  
  148.         (void) signal(SIGINT, SIG_IGN);
  149.         (void) signal(SIGQUIT, SIG_IGN);
  150.         (void) close(p[1]);
  151.  
  152.         /* tell jove the pid of the real child as opposed to us */
  153.         lump.header.pid = getpid();
  154.         lump.header.nbytes = sizeof (pid_t);
  155.         byte_copy((UnivConstPtr) &pid, (UnivPtr) lump.data, sizeof(pid_t));
  156.         /* It is not clear what we can do if this write fails */
  157.         do ; while (write(1, (UnivConstPtr) &lump, sizeof(struct header) + sizeof(pid_t)) < 0
  158.             && errno == EINTR);
  159.  
  160.         /* read proc's output and send it to jove */
  161.         read_pipe(p[0]);
  162.  
  163.         /* received EOF - wait for child to die and then write the
  164.            child's status to JOVE.
  165.  
  166.            Notice that we use a byte count of -1 (an otherwise
  167.            impossible value) as a marker.  JOVE "knows" the real
  168.            length is sizeof(wait_status_t). */
  169.  
  170.         (void) close(p[0]);
  171.         lump.header.pid = getpid();
  172.         lump.header.nbytes = -1;    /* tell jove we are finished */
  173.         /* try to exit like our child did ... */
  174.         {
  175.             wait_status_t    status;
  176.  
  177.             do ; while (wait(&status) != pid);
  178.             byte_copy((UnivPtr)&status, (UnivPtr)lump.data,
  179.                 sizeof(status));
  180.         }
  181.         /* It is not clear what we can do if this write fails */
  182.         do ; while (write(1, (UnivConstPtr) &lump,
  183.             sizeof(struct header) + sizeof(wait_status_t)) < 0
  184.                 && errno == EINTR);
  185.     }
  186. }
  187.  
  188. int
  189. main(argc, argv)
  190. int    argc;
  191. char    **argv;
  192. {
  193.     if (strcmp(argv[0], "kbd") == 0)
  194.         kbd_process();
  195.     else
  196.         portsrv_process(argc, argv);
  197.     return 0;
  198. }
  199.  
  200. #else /* !PIPEPROCS */
  201. int
  202. main()
  203. {
  204.     return 0;
  205. }
  206. #endif /* !PIPEPROCS */
  207.