version 1.2, 2000/02/25 19:13:21 |
version 1.3, 2000/03/03 19:31:26 |
|
|
/* |
/* |
* Name: MicroGnuEmacs |
* Spawn. Actually just suspends Mg. |
* Spawn CLI for System V. |
* Assumes POSIX job control. |
* |
|
* Spawn for System V. |
|
*/ |
*/ |
#include "def.h" |
#include "def.h" |
|
|
#include <signal.h> |
#include <signal.h> |
|
#include <termios.h> |
|
|
char *shellp = NULL; /* Saved "SHELL" program. */ |
|
char *shname = NULL; /* Saved shell name */ |
|
|
|
/* |
/* |
* On System V, we no gots job control, so always run |
* This causes mg to send itself a stop signal. |
* a subshell using fork/exec. Bound to "C-C", and used |
* Assumes the parent shell supports POSIX job control. |
* as a subcommand by "C-Z". (daveb) |
* If the terminal supports an alternate screen, we will sitch to it. |
* |
|
* Returns 0 if the shell executed OK, something else if |
|
* we couldn't start shell or it exited badly. |
|
*/ |
*/ |
|
/* ARGSUSED */ |
spawncli(f, n) |
spawncli(f, n) |
{ |
{ |
register int pid; |
sigset_t oset; |
register int wpid; |
int ttputc __P((int)); /* XXX */ |
register void (*oqsig)(); |
|
register void (*oisig)(); |
|
int status; |
|
int errp = FALSE; |
|
|
|
if (shellp == NULL) { |
/* Very similar to what vttidy() does. */ |
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); |
ttcolor(CTEXT); |
ttnowindow(); |
ttnowindow(); |
ttmove(nrow-1, 0); |
ttmove(nrow - 1, 0); |
if (epresf != FALSE) { |
if (epresf != FALSE) { |
tteeol(); |
tteeol(); |
epresf = FALSE; |
epresf = FALSE; |
} |
} |
ttclose(); |
if (ttcooked() == FALSE) |
sgarbf = TRUE; /* Force repaint. */ |
return (FALSE); |
oqsig = signal(SIGQUIT, SIG_IGN); |
tttidy(); /* Exit application mode and tidy. */ |
oisig = signal(SIGINT, SIG_IGN); |
ttflush(); |
if ((pid=fork()) == 0) { |
(void) sigprocmask(SIG_SETMASK, NULL, &oset); |
(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) |
|
{ |
|
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); |
(void) kill(0, SIGTSTP); |
sigprocmask(SIG_SETMASK, &oldsig, NULL); |
(void) sigprocmask(SIG_SETMASK, &oset, NULL); |
#else |
ttreinit(); |
getchar(); |
sgarbf = TRUE; /* Force repaint. */ |
#endif |
return ttraw(); |
ttopen(); |
|
setttysize(); |
|
ttwindow(); |
|
|
|
return ( 0 ); |
|
} |
} |