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