home *** CD-ROM | disk | FTP | other *** search
/ ftp.freefriends.org / ftp.freefriends.org.tar / ftp.freefriends.org / arnold / Source / mush.rstevens.tar.gz / mush.tar / execute.c < prev    next >
C/C++ Source or Header  |  1994-07-09  |  5KB  |  180 lines

  1. /* execute.c     (c) copyright    10/28/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4. #if defined(BSD) || defined(IRIX4) || defined(POSIX)
  5. #include <sys/wait.h>
  6. #else
  7. #ifndef SYSV
  8. #include <wait.h>
  9. #endif /* SYSV */
  10. #endif /* BSD || IRIX4 */
  11.  
  12. #ifdef lint
  13. #include <sys/resource.h>
  14. #endif /* lint */
  15.  
  16. static jmp_buf execjbuf;
  17.  
  18. #ifdef SUNTOOL
  19.  
  20. /*ARGSUSED*/
  21. Notify_value
  22. my_wait3(tty, pid, status, rusage)
  23. Tty tty;
  24. int pid;
  25. union wait *status;
  26. struct rusage *rusage;
  27. {
  28.     extern Panel_item edit_item;
  29.     Textsw textsw = (Textsw)window_get(tty, WIN_CLIENT_DATA);
  30.     char *file = (char *)window_get(textsw, TEXTSW_CLIENT_DATA);
  31.     int i = 0;
  32.  
  33.     if (WIFSTOPPED(*status)) {
  34.     kill(pid, SIGCONT);
  35.     return (NOTIFY_IGNORED);
  36.     }
  37.     if (pid != exec_pid || exec_pid <= 0) /* if the editor didn't die, return */
  38.     return NOTIFY_DONE;
  39.     /* editor died -- reset exec_pid so no one thinks we're running */
  40.     exec_pid = 0;
  41.     (void) window_set(tty, TTY_ARGV, TTY_ARGV_DO_NOT_FORK, NULL);
  42.     wprint("Editor done.\n");
  43.     (void) window_set(tty_sw, WIN_SHOW, FALSE, NULL);
  44. #ifdef SUN_4_0 /* SunOS 4.0+ */
  45.     (void) window_set(textsw,
  46.     WIN_SHOW,        TRUE,
  47.     TEXTSW_FILE_CONTENTS,    file,
  48.     NULL);
  49. #else /* SUN_4_0 */
  50.     textsw_load_file(textsw, file, 1, 0, 0);
  51.     textsw_set(textsw, WIN_SHOW, TRUE, NULL);
  52. #endif /* SUN_4_0 */
  53.     textsw_normalize_view(textsw, (Textsw_index)0);
  54.     (void) unlink(file);
  55.     set_comp_items(panel_get(edit_item, PANEL_PARENT_PANEL));
  56.  
  57.     return NOTIFY_DONE;
  58. }
  59.  
  60. tool_edit_letter(textsw, argv)
  61. Textsw textsw;
  62. char **argv;
  63. {
  64.     Rect *msg_rect = (Rect *)window_get(textsw, WIN_RECT);
  65.  
  66.     wprint("Starting \"%s\"...\n", *argv);
  67. #ifdef SUN_4_0
  68.     window_set(textsw, WIN_SHOW, FALSE, NULL);
  69. #else /* SUN_4_0 */
  70.     textsw_set(textsw, WIN_SHOW, FALSE, NULL);
  71. #endif /* SUN_4_0 */
  72.     ttysw_output(tty_sw, "\f", 1);  /* clear screen */
  73.     (void) window_set(tty_sw,
  74.     WIN_RECT,    msg_rect,
  75.     TTY_ARGV,    argv,
  76.     WIN_SHOW,    TRUE,
  77.     NULL);
  78.     if ((exec_pid = (int) window_get(tty_sw, TTY_PID)) == -1) {
  79.     error("Couldn't execute %s", *argv);
  80.     return -1;
  81.     }
  82.     notify_set_wait3_func(tty_sw, my_wait3, exec_pid);
  83.     Debug("tty pid = %d\n", exec_pid);
  84.     return 0;
  85. }
  86. #endif /* SUNTOOL */
  87.  
  88. execute(argv)
  89. char **argv;
  90. {
  91. #if defined(SYSV) || defined(POSIX) || defined (BSD44)
  92.     int status;
  93. #else
  94.     union wait status;
  95. #endif /* SYSV || POSIX || BSD44 */
  96. #ifdef SIGCONT
  97.     SIGRET (*oldstop)(), (*oldcont)();
  98. #endif /* SIGCONT */
  99.     int pid;
  100.     SIGRET (*oldint)(), (*oldquit)();
  101.  
  102.     oldint = signal(SIGINT, SIG_IGN);
  103.     oldquit = signal(SIGQUIT, SIG_IGN);
  104. #ifdef SIGCONT
  105.     oldstop = signal(SIGTSTP, SIG_DFL);
  106.     oldcont = signal(SIGCONT, SIG_DFL);
  107. #endif /* SIGCONT */
  108.     turnon(glob_flags, IGN_SIGS);
  109.  
  110.     echo_on();
  111.     if (!setjmp(execjbuf)) {
  112.     if ((exec_pid = vfork()) == 0) {
  113.         (void) signal(SIGINT, SIG_DFL);
  114.         (void) signal(SIGQUIT, SIG_DFL);
  115.         (void) signal(SIGPIPE, SIG_DFL);
  116.         (void) closefileds(3);    /* close all descriptors above 2 */
  117.         execvp(*argv, argv);
  118.         if (errno == ENOENT)
  119.         print("%s: command not found.\n", *argv);
  120.         else
  121.         error(*argv);
  122.         _exit(-1);
  123.     }
  124.     /* Parent's got to do something; sigchldcatcher may also be waiting.
  125.      * This loop will usually get broken by the longjmp() (except tool),
  126.      * but in certain circumstances sigchldcatcher isn't yet active.
  127.      */
  128.     while ((pid = wait(&status)) != -1 && pid != exec_pid)
  129.         Debug("The exec loop caught a signal? (pid = %d)\n", pid);
  130.     }
  131.     /* reset our ttymodes */
  132.     echo_off();
  133.     (void) signal(SIGINT, oldint);
  134.     (void) signal(SIGQUIT, oldquit);
  135. #ifdef SIGCONT
  136.     (void) signal(SIGTSTP, oldstop);
  137.     (void) signal(SIGCONT, oldcont);
  138. #endif /* SIGCONT */
  139.     turnoff(glob_flags, IGN_SIGS);
  140. }
  141.  
  142. SIGRET
  143. sigchldcatcher()
  144. {
  145. #if defined(SYSV) || defined(POSIX) || defined(BSD44)
  146.     int status;
  147. #else
  148.     union wait status;
  149. #endif /* SYSV || POSIX || BSD44 */
  150.     int       pid;
  151.  
  152. #ifdef POSIX /* this could probably be done smarter */
  153.     while ((pid = waitpid(-1,&status, WNOHANG)) > 0) {
  154.     Debug("%d died...\n", pid);
  155.     if (pid == exec_pid)
  156.         break;
  157.     }
  158. #else
  159. #if defined(BSD) || defined(IRIX4)
  160.     while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) {
  161.     Debug("%d died...\n", pid);
  162.     if (pid == exec_pid)
  163.         break;
  164.     }
  165. #else
  166. #ifndef SYSV
  167.     while ((pid = wait2(&status, WNOHANG)) > 0 && pid != exec_pid)
  168.     Debug("%d died...\n", pid);
  169. #else /* SYSV */
  170.     while ((pid = wait((int *)0)) > 0 && pid != exec_pid)
  171.     Debug("%d died...\n", pid);
  172. #endif /* SYSV */
  173. #endif /* BSD || IRIX4 */
  174. #endif /* POSIX */
  175.     if (pid == exec_pid && pid > 0) {
  176.     exec_pid = 0;
  177.     longjmp(execjbuf, 1);
  178.     }
  179. }
  180.