xref: /openbsd/usr.bin/mg/spawn.c (revision 83108e85)
1 /*
2  * Name:	MicroGnuEmacs
3  *		Spawn CLI for System V.
4  *
5  * Spawn for System V.
6  */
7 #include	"def.h"
8 
9 #include	<signal.h>
10 
11 char	*shellp	= NULL;			/* Saved "SHELL" program.	*/
12 char	*shname = NULL;			/* Saved shell name		*/
13 
14 /*
15  * On System V, we no gots job control, so always run
16  * a subshell using fork/exec. Bound to "C-C", and used
17  * as a subcommand by "C-Z". (daveb)
18  *
19  * Returns 0 if the shell executed OK, something else if
20  * we couldn't start shell or it exited badly.
21  */
22 spawncli(f, n)
23 {
24 	register int	pid;
25 	register int	wpid;
26 	register void	(*oqsig)();
27 	register void	(*oisig)();
28 	int		status;
29 	int		errp = FALSE;
30 
31 	if (shellp == NULL) {
32 		shellp = getenv("SHELL");
33 		if (shellp == NULL)
34 			shellp = getenv("shell");
35 		if (shellp == NULL)
36 			shellp = "/bin/sh";	/* Safer.		*/
37 		shname = strrchr( shellp, '/' );
38 		shname = shname ? shname++ : shellp;
39 
40 	}
41 	ttcolor(CTEXT);
42 	ttnowindow();
43 	ttmove(nrow-1, 0);
44 	if (epresf != FALSE) {
45 		tteeol();
46 		epresf = FALSE;
47 	}
48 	ttclose();
49 	sgarbf = TRUE;				/* Force repaint.	*/
50 	oqsig = signal(SIGQUIT, SIG_IGN);
51 	oisig = signal(SIGINT,  SIG_IGN);
52 	if ((pid=fork()) == 0) {
53 		(void) signal(SIGINT, oisig);
54 		(void) signal(SIGQUIT, oqsig);
55 		execlp(shellp, shname, "-i", (char *)NULL);
56 		_exit(1);			/* Should do better!	*/
57 	}
58 	else if (pid > 0) {
59 		while ((wpid=wait(&status))>=0 && wpid!=pid)
60 			;
61 	}
62 	else errp = TRUE;
63 
64 	signal(SIGINT,  oisig);
65 	signal(SIGQUIT, oqsig);
66 	ttopen();
67 	setttysize();
68 	ttwindow();
69 
70 	if(errp)
71 		ewprintf("Failed to create process");
72 
73 	return ( errp | status );
74 }
75 
76 /*
77  * Put the tty in normal mode, so he can do a second ^Z.  Then
78  * wait for a char.  To use ^Z^Z to suspend and "fg %mg CR CR"
79  * to continue;
80  *
81  * Returns 0 if it works, which presumably it must.
82  */
83 attachtoparent(f, n)
84 {
85 	register int	pid;
86 	register int	wpid;
87 	register int	(*oqsig)();
88 	register int	(*oisig)();
89 	int		status;
90 	int		errp = FALSE;
91 	int		omask;
92 	sigset_t	newsig,oldsig;
93 
94 	ttcolor(CTEXT);
95 	ttnowindow();
96 	ttmove(nrow-1, 0);
97 	if (epresf != FALSE) {
98 		tteeol();
99 		epresf = FALSE;
100 	}
101 	ttclose();
102 	sgarbf = TRUE;				/* Force repaint.	*/
103 #ifdef SIGTSTP
104 	sigemptyset(&newsig);
105 	sigprocmask(SIG_SETMASK, &newsig, &oldsig);
106 	(void) kill(0, SIGTSTP);
107 	sigprocmask(SIG_SETMASK, &oldsig, NULL);
108 #else
109 	getchar();
110 #endif
111 	ttopen();
112 	setttysize();
113 	ttwindow();
114 
115 	return ( 0 );
116 }
117