File: execute.c

package info (click to toggle)
mush 7.2.5unoff2-25
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 1,784 kB
  • ctags: 1,342
  • sloc: ansic: 21,890; sh: 972; makefile: 90; csh: 87
file content (171 lines) | stat: -rw-r--r-- 4,262 bytes parent folder | download | duplicates (6)
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);
    }
}