summaryrefslogtreecommitdiff
path: root/usr.bin/mg/spawn.c
blob: 3d3f562b64649506f5547606bcaccd31effe94d2 (plain)
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
/*
 * Name:	MicroGnuEmacs
 *		Spawn CLI for System V.
 *
 * Spawn for System V.
 */
#include	"def.h"

#include	<signal.h>

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

extern	char	*getenv();

/*
 * 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.
 */
spawncli(f, n)
{
	extern char	*strrchr();
	register int	pid;
	register int	wpid;
	register int	(*oqsig)();
	register int	(*oisig)();
	int		status;
	int		errp = FALSE;

	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++ : shellp;
		
	}
	ttcolor(CTEXT);
	ttnowindow();
	ttmove(nrow-1, 0);
	if (epresf != FALSE) {
		tteeol();
		epresf = FALSE;
	}
	ttclose();
	sgarbf = TRUE;				/* Force repaint.	*/
	oqsig = signal(SIGQUIT, SIG_IGN);
	oisig = signal(SIGINT,  SIG_IGN);
	if ((pid=fork()) == 0) {
		(void) signal(SIGINT, oisig);
		(void) signal(SIGQUIT, oqsig);
		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);
	ttopen();
	setttysize();
	ttwindow();

	if(errp)
		ewprintf("Failed to create process");

	return ( errp | status );
}

/*
 * Put the tty in normal mode, so he can do a second ^Z.  Then
 * wait for a char.  To use ^Z^Z to suspend and "fg %mg CR CR"
 * to continue;
 *
 * Returns 0 if it works, which presumably it must.
 */
attachtoparent(f, n)
{
	extern char	*strrchr();
	register int	pid;
	register int	wpid;
	register int	(*oqsig)();
	register int	(*oisig)();
	int		status;
	int		errp = FALSE;
	int		omask;
	sigset_t	newsig,oldsig;

	ttcolor(CTEXT);
	ttnowindow();
	ttmove(nrow-1, 0);
	if (epresf != FALSE) {
		tteeol();
		epresf = FALSE;
	}
	ttclose();
	sgarbf = TRUE;				/* Force repaint.	*/
#ifdef SIGTSTP
	sigemptyset(&newsig);
	sigprocmask(SIG_SETMASK, &newsig, &oldsig);
	(void) kill(0, SIGTSTP);
	sigprocmask(SIG_SETMASK, &oldsig, NULL);
#else
	getchar();
#endif
	ttopen();
	setttysize();
	ttwindow();

	return ( 0 );
}