home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume11 / mush5.7 / part02 / execute.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-09-16  |  4.3 KB  |  158 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. #endif SUNTOOL
  89. #ifdef SYSV
  90.     int status;
  91. #else
  92.     union wait status;
  93. #endif SYSV
  94.     int       pid;
  95.  
  96. #ifdef BSD
  97.     /* The follwoing SHOULDN'T be necessary, but it is!!! ttysw_fork()
  98.      * returns the pid of the thing that it executes, but that's not the
  99.      * pid that dies!  There are many procs that might die from ttysw_fork
  100.      * one of them is the process, another is the tty, etc... other
  101.      * procs that might die are sendmail, fortune, etc... tool_sigchld()
  102.      * handles these, but we can't let it have control unless we KNOW the
  103.      * editor is done.
  104.      * so if what we catch is not the exec_pid from ttysw_fork(), then
  105.      * send ourselves a sigchld to go thru this routine again.  mush -d
  106.      */
  107.     while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) {
  108.     Debug("%d died...\n", pid);
  109.     if (pid == exec_pid)
  110.         break;
  111.     }
  112. #else
  113. #ifndef SYSV
  114.     while ((pid = wait2(&status, WNOHANG)) > 0 && pid != exec_pid)
  115.     Debug("%d died...\n", pid);
  116. #else SYSV
  117.     while ((pid = wait((int *)0)) > 0 && pid != exec_pid)
  118.     Debug("%d died...\n", pid);
  119. #endif SYSV
  120. #endif BSD
  121. #ifndef SUNTOOL
  122.     }
  123. #else SUNTOOL
  124.     if (pid != exec_pid || exec_pid <= 0) /* if the editor didn't die, return */
  125.     return;
  126.     /* editor died -- reset exec_pid so no one thinks we're running */
  127.     exec_pid = 0;
  128.     /* only the tool needs to continue from here.  Reset the win */
  129.     if (istool < 1)
  130.     return;
  131.     tool_sigchld(tool);
  132.     print("Editor done");
  133.     win_getrect(tty_sw->ts_windowfd, &msg_rect);
  134.     if (!msg_rect.r_height) {
  135.     print_more(" (well, something just happened)");
  136.     return;
  137.     }
  138.     rect.r_top = rect.r_left = rect.r_height = 0;
  139.     rect.r_width = msg_rect.r_width;
  140.     win_setrect(tty_sw->ts_windowfd, &rect);
  141.     win_setrect(msg_sw->ts_windowfd, &msg_rect);
  142.     panel_set(comp_item, PANEL_SHOW_ITEM, FALSE, 0);
  143.     panel_set(send_item, PANEL_SHOW_ITEM, TRUE, 0);
  144.     panel_set(edit_item, PANEL_SHOW_ITEM, TRUE, 0);
  145.     panel_set(abort_item, PANEL_SHOW_ITEM, TRUE, 0);
  146.     wprint("(continue editing letter.)\n");
  147.     pw_char(msg_win, txt.x,txt.y, PIX_SRC, fonts[curfont], '_');
  148. }
  149.  
  150. sigtermcatcher()
  151. {
  152.     ttysw_done(tty_sw->ts_data);
  153.     if (ison(glob_flags, IS_GETTING))
  154.     rm_edfile(-1);
  155.     cleanup(SIGTERM);
  156. }
  157. #endif SUNTOOL
  158.