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