* more ile
@ 1992-03-30 18:15 Scott Schwartz
0 siblings, 0 replies; only message in thread
From: Scott Schwartz @ 1992-03-30 18:15 UTC (permalink / raw)
To: rc
Here are some hacks on ile to make it use Dan Bernstein's pty program,
rather than doing pty munging for itself. After a whole hour of use,
it seems to mostly work. :-) Some previous features got left out for
no reason (like lflag). New features are that utmp and pty
mode/ownership are now correctly maintained (although you'll need a
patch for pty to make the latter work straight: comment out line 234 of
ptymisc.c)
(context diff from roughly the version that Rich posted most recently.)
*** 1.3 1992/02/09 07:16:44
--- ile.c 1992/03/30 18:12:47
***************
*** 34,39 ****
--- 34,42 ----
**
** Uses the termcap library.
*/
+ /*
+ ** Hacked on by Rich Salz and Scott Schwartz.
+ */
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
***************
*** 46,51 ****
--- 49,55 ----
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
+ #include <sys/socket.h>
#include <sys/file.h>
#include <sys/time.h>
***************
*** 157,164 ****
int TTYmode;
int TTYmaster;
int TTYslave;
- char ttydev[] = "/dev/ttyxx";
- char ptydev[] = "/dev/ptyxx";
/* Definitions of system stuff. */
extern int optind;
--- 161,166 ----
***************
*** 177,216 ****
extern void exit();
extern void _exit();
-
- /*
- ** Open a pty. Try pairs in order until we find a free one.
- */
- void
- getpty()
- {
- char *letter;
- char *devindex;
- int i;
- int j;
-
- i = strlen(ttydev);
- j = strlen(ptydev);
- for (letter = "pqrstuvwxyz"; *letter; letter++) {
- ttydev[i - 2] = *letter;
- ptydev[j - 2] = *letter;
- for (devindex = "0123456789abcdef"; *devindex; devindex++) {
- ttydev[i - 1] = *devindex;
- ptydev[j - 1] = *devindex;
- if ((TTYmaster = open(ptydev, O_RDWR)) >= 0) {
- if ((TTYslave = open(ttydev, O_RDWR)) >= 0)
- return;
- (void)close(TTYmaster);
- }
- }
- }
-
- perror("ile (can't get pty)");
- exit(1);
- /* NOTREACHED */
- }
-
-
/*
** Move past the digits and * in front of an termcap entry.
*/
--- 179,184 ----
***************
*** 287,365 ****
TTYnewsize = TRUE;
}
-
- /*
- ** set/clear the utmp slot for the pty
- */
- void
- setutmp(set)
- BOOL set;
- {
- int f;
- int old0;
- int old1;
- int old2;
- int slot;
- struct utmp ut;
- struct passwd *pw;
- char *p;
-
- /* Must make fd's 0,1,2 correspond to TTYslave for ttyslot() to
- * function. Ugh! Why doesn't ttyslot() accept a fd argument? */
- old0 = dup(0);
- old1 = dup(1);
- old2 = dup(2);
- if (old0 < 0 || old1 < 0 || old2 < 0) {
- perror("ile: dup");
- return;
- }
-
- (void)dup2(TTYslave, 0);
- (void)dup2(TTYslave, 1);
- (void)dup2(TTYslave, 2);
- slot = ttyslot();
-
- /* put the fd's back */
- (void)dup2(old0, 0);
- (void)dup2(old1, 1);
- (void)dup2(old2, 2);
- (void)close(old0);
- (void)close(old1);
- (void)close(old2);
-
- if (slot < 0) {
- perror("ile (who are you?)");
- return;
- }
-
- if ((f = open("/etc/utmp", O_WRONLY)) < 0)
- return;
-
- bzero((char *)&ut, sizeof ut);
-
- if (set) {
- if ((pw = getpwuid(getuid())) == NULL) {
- perror("ile (getpwuid failed)");
- (void)close(f);
- return;
- }
-
- /* skip "/dev/" */
- if ((p = rindex(ttydev, '/')) == NULL)
- p = ttydev;
- else
- p++;
-
- (void)strncpy(ut.ut_line, p, sizeof ut.ut_line);
- (void)strncpy(ut.ut_name, pw->pw_name, sizeof ut.ut_name);
- (void)time(&ut.ut_time);
- }
- (void)lseek(f, (long)(slot * sizeof ut), L_SET);
- (void)write(f, (char *)&ut, sizeof ut);
- (void)close(f);
- }
-
-
/*
** Clean up and leave. This function is bound to the SIGCHLD signal so
** that when the child process exits, so does ile. It is also called when
--- 255,260 ----
***************
*** 372,390 ****
/* kill off the child process */
(void)ioctl(TTYslave, TIOCGPGRP, (char *)&pgrp);
! (void)killpg(pgrp, SIGTERM);
!
! /* "logout" the user */
! setutmp(FALSE);
!
! /* restore TTY, close PTY */
! (void)ioctl(STDIN, TIOCSETP, &TTYsgttyb);
! (void)ioctl(STDIN, TIOCSETC, &TTYtchars);
! (void)ioctl(STDIN, TIOCSLTC, &TTYltchars);
! (void)ioctl(STDIN, TIOCLSET, &TTYmode);
(void)close(TTYmaster);
(void)close(TTYslave);
-
/* make things look nice */
PUT(cnl);
exit(0);
--- 267,276 ----
/* kill off the child process */
(void)ioctl(TTYslave, TIOCGPGRP, (char *)&pgrp);
! (void)killpg(pgrp, SIGHUP);
! /*(void)killpg(pgrp, SIGTERM);*/
(void)close(TTYmaster);
(void)close(TTYslave);
/* make things look nice */
PUT(cnl);
exit(0);
***************
*** 1619,1666 ****
(void)signal(SIGINT, clean_up);
(void)signal(SIGWINCH, change_window);
- /* Get the current ttys state and copy it to the TTYslave. */
- (void)ioctl(STDIN, TIOCGETP, &TTYsgttyb);
- (void)ioctl(TTYslave, TIOCSETP, &TTYsgttyb);
- (void)ioctl(STDIN, TIOCGETD, &i);
- (void)ioctl(TTYslave, TIOCSETD, &i);
- (void)ioctl(STDIN, TIOCGETC, &TTYtchars);
- (void)ioctl(TTYslave, TIOCSETC, &TTYtchars);
- (void)ioctl(STDIN, TIOCLGET, &TTYmode);
- (void)ioctl(TTYslave, TIOCLSET, &TTYmode);
- (void)ioctl(STDIN, TIOCGLTC, &TTYltchars);
- (void)ioctl(TTYslave, TIOCSLTC, &TTYltchars);
- (void)ioctl(STDIN, TIOCGWINSZ, &TTYwinsize);
- (void)ioctl(TTYslave, TIOCSWINSZ, &TTYwinsize);
TTYnewsize = FALSE;
- /* "login" the user */
- setutmp(TRUE);
-
- /* Simulate RAW but allow original parity to work. Thus we use
- * CBREAK with all the options turned off. */
- params = TTYsgttyb;
- params.sg_flags = CBREAK;
- (void)ioctl(STDIN, TIOCSETP, ¶ms);
- tchars = TTYtchars;
- tchars.t_intrc = -1;
- tchars.t_quitc = -1;
- tchars.t_startc = -1;
- tchars.t_stopc = -1;
- tchars.t_eofc = -1;
- tchars.t_brkc = -1;
- (void)ioctl(STDIN, TIOCSETC, &tchars);
- ltchars = TTYltchars;
- ltchars.t_suspc = -1;
- ltchars.t_dsuspc = -1;
- ltchars.t_rprntc = -1;
- ltchars.t_flushc = -1;
- ltchars.t_lnextc = -1;
- (void)ioctl(STDIN, TIOCSLTC, <chars);
-
- i = LNOFLSH | LDECCTQ | LLITOUT;
- (void)ioctl(STDIN, TIOCLSET, &i);
-
/* Set up the editor. */
edit = edit_0;
point = 0;
--- 1505,1512 ----
***************
*** 1721,1772 ****
** The child process. Make the pty the controlling terminal and bind it
** to stdin, stdout, and stderr. Then exec the users program.
*/
- void
- child(lflag, av)
- BOOL lflag;
- char *av[];
- {
- char *new;
- char *path;
- int tty;
-
- /* close all file descriptors */
- (void)close(STDIN);
- (void)close(STDOUT);
- (void)close(STDERR);
- (void)close(TTYslave);
- (void)close(TTYmaster);
! /* get the pty as the controlling terminal */
! if ((tty = open("/dev/tty", O_RDWR) < 0)
! || ioctl(tty, TIOCNOTTY, 0) < 0
! || close(tty) < 0)
! perror("ile");
! if ((TTYslave = open(ttydev, O_RDWR)) < 0)
! perror("ile");
! else {
! (void)dup2(TTYslave, STDOUT);
! (void)dup2(TTYslave, STDERR);
}
-
- /* Get pathname. */
- path = av[0];
- if ((av[0] = strrchr(path, '/')) != NULL)
- av[0]++;
- else
- av[0] = path;
- if (lflag) {
- new = malloc((unsigned int)(1 + strlen(av[0]) + 1));
- new[0] = '-';
- (void)strcpy(&new[1], av[0]);
- av[0] = new;
- }
- (void)execvp(path, av);
- perror(path);
- _exit(1);
- /* NOTREACHED */
}
/*
** Set up default key bindings and delimeters.
--- 1567,1623 ----
** The child process. Make the pty the controlling terminal and bind it
** to stdin, stdout, and stderr. Then exec the users program.
*/
! void fork_pty (mp, sp, lflag, args)
! int *mp, *sp;
! int lflag;
! char *args;
! {
! int sv[2];
! char buf[1024];
!
! if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sv) < 0)
! perror("socketpair"), exit(1);
!
! switch (fork()) {
! case -1:
! perror("fork");
! exit(1);
! case 0:
! {int i; for (i = 0; i < FD_SETSIZE; ++i) if (i != sv[1]) close(i); }
! dup(sv[1], 0); dup(sv[1], 1); dup(sv[1], 2);
! strcpy(buf, "/bin/tty;exec ");
! strcat(buf, args);
! execlp("pty", "pty", "-D", "-xuc", "/bin/sh", "-c", buf, 0);
! perror("execlp");
! _exit(1);
! /*NOTREACHED*/
! }
! close(sv[1]);
! *mp = sv[0];
! read_line(*mp, buf, sizeof(buf));
! if ((*sp = open(buf, 2)) < 0) {
! write(2, "ile/slave: `", 12);
! write(2, buf, strlen(buf));
! write(2, "': ", 3);
! perror("open");
! exit(1);
}
}
+ int read_line(fd, buf, n)
+ int fd; char* buf; int n;
+ {
+ int r;
+ while (--n > 0) {
+ r = read(fd, buf, 1);
+ if (r <= 0) break;
+ if (*buf == '\r') continue;
+ if (*buf == '\n') break;
+ ++buf;
+ }
+ *buf = 0;
+ }
/*
** Set up default key bindings and delimeters.
***************
*** 2069,2076 ****
}
/* Configure ourserlves. */
! PUT("ile Rev. 2($Revision: 1.3 $)\n");
! getpty();
get_termcap();
if ((homedir = getenv("HOME")) == NULL)
homedir = "/";
--- 1920,1926 ----
}
/* Configure ourserlves. */
! PUT("ile Rev. 2 ($Author: schwartz $ $Revision: 1.9 $)\n");
get_termcap();
if ((homedir = getenv("HOME")) == NULL)
homedir = "/";
***************
*** 2078,2097 ****
user_bindings(initfile);
if (getwd(currentdir) == NULL)
(void)strcpy(currentdir, homedir);
!
! i = fork();
! switch (i) {
! default: /* parent process */
! ile();
! break;
! case 0: /* child process */
! child(lflag, av);
! /* NOTREACHED */
! case -1: /* fork failed */
! perror("ile");
! exit(1);
! /* NOTREACHED */
! }
exit(0);
return 0;
}
--- 1928,1935 ----
user_bindings(initfile);
if (getwd(currentdir) == NULL)
(void)strcpy(currentdir, homedir);
! fork_pty (&TTYmaster, &TTYslave, lflag, av[0]);
! ile();
exit(0);
return 0;
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~1992-03-30 18:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1992-03-30 18:15 more ile Scott Schwartz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).