This is x_extrnl.c in view mode; [Download] [Up]
/*
* Spawn a shell with the stdin and stdout swapped with the remote
* system, ie:
* +----------+
* TTYin ------------> stdin | |
* | shell |
* TTYout <---------- stdout | |
* +----------+
*
* An undocumented feature: The external protocol gateway
* can be used to pipe the output of a normal Unix command to the
* remote system.
*/
#include <stdio.h>
#include <signal.h>
#include <curses.h>
#include <errno.h>
#include "config.h"
#ifdef BSD
#ifndef SIGCLD
#define SIGCLD SIGCHLD
#endif /* SIGCLD */
#include <sys/file.h>
#else /* BSD */
#include <fcntl.h>
#endif /* BSD */
void
do_extrnl(cmd)
char *cmd;
{
extern int fd, errno;
WINDOW *xt_win, *newwin();
SIG_TYPE (*istat)(), (*qstat)(), (*cstat)();
int epid, want_out;
unsigned int sleep();
void _exit(), input_off();
input_off();
/* a full window */
xt_win = newwin(LINES, COLS, 0, 0);
nl();
touchwin(xt_win);
wrefresh(xt_win);
if (!(epid = fork())) {
/* create a new process group ID */
#ifdef BSD
setpgrp(0, getpid());
#else /* BSD */
setpgrp();
#endif /* BSD */
/* swap the stdin */
close(0);
dup(fd);
/* swap the stdout */
close(1);
dup(fd);
#ifdef SETUGID
setgid(getgid());
setuid(getuid());
#endif /* SETUGID */
execl("/bin/sh", "sh", "-c", cmd, (char *) 0);
_exit(1);
}
istat = signal(SIGINT, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
cstat = signal(SIGCLD, SIG_IGN);
/*
* Check the keyboard while the external program is running. If
* the user hits the <ESC> key, then kill the entire process
* group associated with the new shell.
*/
want_out = 0;
while(1) {
switch(wait_key(stdscr, 1)) {
case -1: /* timed out */
break;
case 27: /* a user abort */
#ifdef BSD
killpg(epid, SIGKILL);
#else /* BSD */
kill(-epid, SIGKILL);
#endif /* BSD */
want_out++;
break;
default:
beep();
break;
}
if (want_out)
break;
/* see if the process it still active */
if ((kill(epid, 0) == -1) && errno == ESRCH)
break;
}
signal(SIGINT, istat);
signal(SIGQUIT, qstat);
signal(SIGCLD, cstat);
/* the tty may have been clobbered */
sleep(1);
fixterm();
nonl();
clearok(curscr, TRUE);
werase(xt_win);
wrefresh(xt_win);
delwin(xt_win);
return;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.