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.