home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / mush6.4 / part03 / execute.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-12  |  5.7 KB  |  199 lines

  1. /* execute.c     (c) copyright    10/28/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4. #ifdef BSD
  5. #include <sys/wait.h>
  6. #else
  7. #ifndef SYSV
  8. #include <wait.h>
  9. #endif /* SYSV */
  10. #endif /* BSD */
  11.  
  12. #ifdef lint
  13. #include <sys/resource.h>
  14. #endif /* lint */
  15.  
  16. execute(argv)
  17. char **argv;
  18. {
  19. #ifdef SYSV
  20.     int status;
  21. #else
  22.     union wait status;
  23. #endif /* SYSV */
  24. #ifdef SIGCONT
  25.     SIGRET (*oldstop)(), (*oldcont)();
  26. #endif /* SIGCONT */
  27.     int pid;
  28.     SIGRET (*oldint)(), (*oldquit)();
  29.  
  30. #ifdef SUNTOOL
  31.     if (istool) {
  32.     print("Editing letter...");
  33.  
  34.     panel_set(abort_item, PANEL_SHOW_ITEM, FALSE, 0);
  35.     panel_set(send_item,  PANEL_SHOW_ITEM, FALSE, 0);
  36.     panel_set(edit_item,  PANEL_SHOW_ITEM, FALSE, 0);
  37.     win_setrect(tty_sw->ts_windowfd, &msg_rect);
  38.     msg_rect.r_height = 0;
  39.     win_setrect(msg_sw->ts_windowfd, &msg_rect);
  40.     if ((exec_pid = ttysw_fork(tty_sw->ts_data, argv,
  41.         &tty_sw->ts_io.tio_inputmask,
  42.         &tty_sw->ts_io.tio_outputmask,
  43.         &tty_sw->ts_io.tio_exceptmask)) == -1)
  44.         error("%s failed", *argv), sigchldcatcher();
  45.     Debug("tty pid = %d\n", exec_pid);
  46.     return;
  47.     }
  48. #endif /* SUNTOOL */
  49.     oldint = signal(SIGINT, SIG_IGN);
  50.     oldquit = signal(SIGQUIT, SIG_IGN);
  51. #ifdef SIGCONT
  52.     oldstop = signal(SIGTSTP, SIG_DFL);
  53.     oldcont = signal(SIGCONT, SIG_DFL);
  54. #endif /* SIGCONT */
  55.     turnon(glob_flags, IGN_SIGS);
  56.  
  57.     echo_on();
  58.     if ((exec_pid = vfork()) == 0) {
  59.     (void) signal(SIGINT, SIG_DFL);
  60.     (void) signal(SIGQUIT, SIG_DFL);
  61.     (void) signal(SIGPIPE, SIG_DFL);
  62.     (void) closefileds(3);    /* close all descriptors above 2 */
  63.     execvp(*argv, argv);
  64.     if (errno == ENOENT)
  65.         print("%s: command not found.\n", *argv);
  66.     else
  67.         error(*argv);
  68.     _exit(-1);
  69.     }
  70.     /* parent's got to do something; sigchldcatcher will do waiting
  71.      * if other forks die (sendmail), then this wait will catch them,
  72.      * This loop will really get -1, cuz sigchldcatcher will catch all else.
  73.      */
  74.     while ((pid = wait(&status)) != -1 && pid != exec_pid)
  75.     Debug("The exec loop caught a signal? (pid = %d)\n", pid);
  76.     /* reset our ttymodes */
  77.     echo_off();
  78.     (void) signal(SIGINT, oldint);
  79.     (void) signal(SIGQUIT, oldquit);
  80. #ifdef SIGCONT
  81.     (void) signal(SIGTSTP, oldstop);
  82.     (void) signal(SIGCONT, oldcont);
  83. #endif /* SIGCONT */
  84.     turnoff(glob_flags, IGN_SIGS);
  85. }
  86.  
  87. SIGRET
  88. sigchldcatcher()
  89. {
  90. #ifdef SUNTOOL
  91.     struct rect rect;
  92.     extern FILE *ed_fp;
  93. #endif /* SUNTOOL */
  94. #ifdef SYSV
  95.     int status;
  96. #else
  97.     union wait status;
  98. #endif /* SYSV */
  99.     int       pid;
  100.  
  101. #ifdef BSD
  102.     /* The following SHOULDN'T be necessary, but it is!!! ttysw_fork()
  103.      * returns the pid of the thing that it executes, but that's not the
  104.      * pid that dies!  There are many procs that might die from ttysw_fork
  105.      * one of them is the process, another is the tty, etc... other
  106.      * procs that might die are sendmail, fortune, etc... tool_sigchld()
  107.      * handles these, but we can't let it have control unless we KNOW the
  108.      * editor is done.
  109.      * so if what we catch is not the exec_pid from ttysw_fork(), then
  110.      * send ourselves a sigchld to go thru this routine again.  mush -d
  111.      */
  112.     while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) {
  113.     Debug("%d died...\n", pid);
  114.     if (pid == exec_pid)
  115.         break;
  116.     }
  117. #else
  118. #ifndef SYSV
  119.     while ((pid = wait2(&status, WNOHANG)) > 0 && pid != exec_pid)
  120.     Debug("%d died...\n", pid);
  121. #else /* SYSV */
  122.     while ((pid = wait((int *)0)) > 0 && pid != exec_pid)
  123.     Debug("%d died...\n", pid);
  124. #endif /* SYSV */
  125. #endif /* BSD */
  126. #ifndef SUNTOOL
  127.     }
  128. #else /* SUNTOOL */
  129.     if (pid != exec_pid || exec_pid <= 0) /* if the editor didn't die, return */
  130.     return;
  131.     /* editor died -- reset exec_pid so no one thinks we're running */
  132.     exec_pid = 0;
  133.     /* only the tool needs to continue from here.  Reset the win */
  134.     if (istool < 1)
  135.     return;
  136.     tool_sigchld(tool);
  137.     print("Editor done.");
  138.     win_getrect(tty_sw->ts_windowfd, &msg_rect);
  139.     if (msg_rect.r_height < 2 * l_height(curfont)) {
  140.     print_more(" (well, something just happened)");
  141.     return;
  142.     }
  143.     {
  144.     extern char *edfile;
  145.     if (!(ed_fp = fopen(edfile, "r+")))
  146.         error("can't reopen %s", edfile);
  147.     (void) fseek(ed_fp, 0L, 2);
  148.     }
  149.     /* I'd like to be able to just pw_rop the tty window onto the window
  150.      * we're going to use now, but I can't access the data structure!
  151.      *
  152.      * pw_rop(msg_win, 0, 0, msg_rect.r_width, msg_rect.r_height, PIX_SRC,
  153.      *        ((struct ??? *)(tty_sw->ts_data))->pr_pixrect, 0, 0);
  154.      * So, instead, just clear the window and write the last N lines from the
  155.      * end of the file into the window.
  156.      */
  157.     rect.r_top = rect.r_left = rect.r_height = 0;
  158.     rect.r_width = msg_rect.r_width;
  159.     win_setrect(tty_sw->ts_windowfd, &rect);
  160.     win_setrect(msg_sw->ts_windowfd, &msg_rect);
  161.     do_clear();
  162.     /* read the last 2K bytes in the file -- search backwards for enough
  163.      * carriage returns that will fill the window with the end of the letter
  164.      * written so far and display the text.
  165.      */
  166.     {
  167.     register long where = ftell(ed_fp);
  168.     register int cr = 0, lines = msg_rect.r_height * l_height(curfont) - 3;
  169.     char buf[2*BUFSIZ], *p;
  170.     where = max(0, where-2*BUFSIZ);
  171.     (void) fseek(ed_fp, where, L_SET);
  172.     p = buf + read(fileno(ed_fp), buf, 2*BUFSIZ);
  173.     *p = 0;
  174.     while (cr < lines && p > buf)
  175.         if (*--p == '\n')
  176.         cr++;
  177.     if (p > buf)
  178.         while (*p != '\n')
  179.         p++;
  180.     Addstr(p);
  181.     }
  182.     panel_set(comp_item, PANEL_SHOW_ITEM, FALSE, 0);
  183.     panel_set(send_item, PANEL_SHOW_ITEM, TRUE, 0);
  184.     panel_set(edit_item, PANEL_SHOW_ITEM, TRUE, 0);
  185.     panel_set(abort_item, PANEL_SHOW_ITEM, TRUE, 0);
  186.     wprint("(continue editing letter.)\n");
  187.     type_cursor(PIX_SRC);
  188. }
  189.  
  190. SIGRET
  191. sigtermcatcher()
  192. {
  193.     ttysw_done(tty_sw->ts_data);
  194.     if (ison(glob_flags, IS_GETTING))
  195.     rm_edfile(-1);
  196.     cleanup(SIGTERM);
  197. }
  198. #endif /* SUNTOOL */
  199.