File: spawn.c

package info (click to toggle)
ng 1.5~beta1-10
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 5,144 kB
  • sloc: ansic: 43,437; asm: 3,150; sh: 2,539; cpp: 1,234; makefile: 577
file content (243 lines) | stat: -rw-r--r-- 5,858 bytes parent folder | download | duplicates (7)
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/* $Id: spawn.c,v 1.3 2000/11/23 14:00:50 amura Exp $ */
/*
 * Name:	MicroGnuEmacs
 *		Spawn CLI for System V.
 *
 * Spawn for System V.
 */

/*
 * $Log: spawn.c,v $
 * Revision 1.3  2000/11/23 14:00:50  amura
 * fix for some strict compiler
 *
 * Revision 1.2  2000/06/27 01:59:43  amura
 * small bugfix
 *
 * Revision 1.1.1.1  2000/06/27 01:47:59  amura
 * import to CVS
 *
 */

#include	"config.h"	/* 90.12.20  by S.Yoshida */
#include	"def.h"

#include	<signal.h>

char	*shellp	= NULL;			/* Saved "SHELL" program.	*/
char	*shname = NULL;			/* Saved shell name		*/

extern	char	*getenv();
#ifdef HAVE_GETSID
extern	int	job_control;
#endif

/*
 * On System V, we no gots job control, so always run
 * a subshell using fork/exec. Bound to "C-C", and used
 * as a subcommand by "C-Z". (daveb)
 *
 * Returns 0 if the shell executed OK, something else if
 * we couldn't start shell or it exited badly.
 */
/*ARGSUSED*/
spawncli(f, n)
{
	extern char	*strrchr();
	register int	pid;
	register int	wpid;
	register VOID	(*oqsig)();
	register VOID	(*oisig)();
#ifdef	ADDFUNC		/* 93.07.08  by S.Yoshida */
#ifdef	SIGWINCH	/* 93.07.08  by S.Yoshida */
	register VOID	(*owsig)();
#endif
#ifdef	SIGTSTP	/* 93.07.08  by S.Yoshida */
	register int	omask;
#endif
#endif	/* ADDFUNC */
	int		status = FALSE;
	int		errp = FALSE;

#ifdef XKEYS  /* 92.03.16 by Gen KUROKI */
	ttykeymaptidy();
#endif /* XKEYS */
	if (shellp == NULL) {
		shellp = getenv("SHELL");
		if (shellp == NULL)
			shellp = getenv("shell");
		if (shellp == NULL)
			shellp = "/bin/sh";	/* Safer.		*/
		shname = strrchr( shellp, '/' ); 
		shname = shname ? shname+1 : shellp;
	}
	ttcolor(CTEXT);
	ttnowindow();
#ifdef	ADDFUNC	/* 93.07.08  by S.Yoshida */
#ifdef	SIGTSTP	/* 93.07.08  by S.Yoshida */
	if (strcmp(shellp, "/bin/csh") == 0) {
		if (epresf != FALSE) {
			ttmove(nrow-1, 0);
			tteeol();
			epresf = FALSE;
		}				/* Csh types a "\n"	*/
		ttmove(nrow-2, 0);		/* before "Stopped".	*/
	} else {
#endif
#endif
	ttmove(nrow-1, 0);
	if (epresf != FALSE) {
		tteeol();
		epresf = FALSE;
	}
#ifdef	ADDFUNC	/* 93.07.08  by S.Yoshida */
#ifdef	SIGTSTP	/* 93.07.08  by S.Yoshida */
	}
#endif
#endif
	ttclose();
	sgarbf = TRUE;				/* Force repaint.	*/
#ifdef	ADDFUNC	/* 93.07.08  by S.Yoshida */
#ifdef	SIGTSTP	/* 93.07.08  by S.Yoshida */
# ifdef HAVE_GETSID
	if (job_control) {
# else
	if (strcmp(shellp, "/bin/sh")!=0 ||
	    getenv("BASH_VERSION") || getenv("BASH"))	{
		/* C shell, ksh	or bash	*/
# endif
	    /*	omask = sigsetmask(0);  */
		oqsig = signal(SIGQUIT, SIG_IGN);
		oisig = signal(SIGINT,  SIG_IGN);
#ifdef	SIGWINCH	/* 93.07.08  by S.Yoshida */
		owsig = signal(SIGWINCH, SIG_IGN);
#endif
		(void) kill(0, SIGTSTP);
	    /*	(void) sigsetmask(omask); */
		signal(SIGINT,  oisig);
		signal(SIGQUIT, oqsig);
#ifdef	SIGWINCH	/* 93.07.08  by S.Yoshida */
		signal(SIGWINCH, owsig);
#endif
	} else {				/* Bourne shell.	*/
#endif	/* SIGTSTP */	
#endif	/* ADDFUNC */
	oqsig = signal(SIGQUIT, SIG_IGN);
	oisig = signal(SIGINT,  SIG_IGN);
#ifdef	ADDFUNC		/* 93.07.08  by S.Yoshida */
#ifdef	SIGWINCH	/* 93.07.08  by S.Yoshida */
	owsig = signal(SIGWINCH, SIG_IGN);
#endif
#endif
	if ((pid=fork()) == 0) {
		(void) signal(SIGINT, oisig);
		(void) signal(SIGQUIT, oqsig);
#ifdef	ADDFUNC		/* 93.07.08  by S.Yoshida */
#ifdef	SIGWINCH	/* 93.07.08  by S.Yoshida */
		(void) signal(SIGWINCH, owsig);
#endif
#endif
#ifdef	EXTD_DIR
		dirend();
#endif
		execlp(shellp, shname, "-i", (char *)NULL);
		_exit(1);			/* Should do better!	*/
	}
	else if (pid > 0) {
		while ((wpid=wait(&status))>=0 && wpid!=pid)
			;
	}
	else errp = TRUE;

	signal(SIGINT,  oisig);
	signal(SIGQUIT, oqsig);
#ifdef	ADDFUNC		/* 93.07.08  by S.Yoshida */
#ifdef	SIGWINCH	/* 93.07.08  by S.Yoshida */
	signal(SIGWINCH, owsig);
#endif
#ifdef	SIGTSTP	/* 93.07.08  by S.Yoshida */
	}
#endif
#endif
	ttopen();
#ifdef SIGWINCH		/* by A.ITO  21 Jan. 1991 / by S.Yoshida */
	refresh(FFRAND, 0);		/* May be resized.	*/
#endif
	if(errp)
		ewprintf("Failed to create process");
#ifdef XKEYS  /* 92.03.16 by Gen KUROKI */
	ttykeypadstart();
#endif /* XKEYS */

	return !( errp | status );
}

#ifndef NO_SHELL	/* 91.01.10  by K.Maeda */
#include <sys/types.h>
#include <sys/stat.h>
/*
 *	Call process in subshell.
 * Execute COMMAND binding standard input to file INPUT.
 * NULL as INPUT means standard input should be bound to
 * /dev/null or whatever equivalent in your OS.
 * All output during the execution (including standard error output)
 * should go into a scratch file, whose name call_process() returns.
 * Return value NULL means error in some stage of the execution.
 * In that case, scratch file should be deleted.
 */
char *
call_process(command, input)
char *command;
char *input;
{
	char buf[256];
	char *tmp;
	static char tmpbuf[20];
	int ostdin, ostdout, ostderr, in, out, s;
	extern char *mktemp();

	strcpy(tmpbuf, "/tmp/ngXXXXXX");
	if ((tmp = mktemp(tmpbuf)) == NULL)
		return NULL;
	if ((in = open(input ? input : "/dev/null", 0)) < 0)
		return NULL;
	if ((out = creat(tmp, S_IREAD | S_IWRITE)) < 0) {
		close(in);
		return NULL;
	}
	ostdin = dup(0); ostdout = dup(1); ostderr = dup(2);
	if (ostdin < 0 || ostdout < 0 || ostderr < 0) {
		s = -1;
		goto skip;
	}
#ifndef	SVR2	/* 91.02.04  SVR3 or later. by Junn Ohta */
	dup2(in, 0);
	dup2(out, 1);
	dup2(out, 2);
#else	/* SVR2 */
	close(0); dup(in);
	close(1); dup(out);
	close(2); dup(out);
#endif	/* SVR2 */
	strcpy(buf, command);
#ifdef	EXTD_DIR
	ensurecwd();
#endif
	s = system(buf);
	close(in);
	close(out);
#ifndef	SVR2	/* 91.02.04  SVR3 or later. by Junn Ohta */
	dup2(ostdin, 0); dup2(ostdout, 1); dup2(ostderr, 2);
#else	/* SVR2 */
	close(0); dup(ostdin);
	close(1); dup(ostdout);
	close(2); dup(ostderr);
#endif	/* SVR2 */
skip:	close(ostdin); close(ostdout); close(ostderr);
	if (s == -1) {
		unlink(tmp);
		return NULL;
	}
	return tmp;
}
#endif	/* NO_SHELL */