rc-list - mailing list for the rc(1) shell
 help / color / mirror / Atom feed
* 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, &params);
-     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, &ltchars);
- 
-     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).