reading chars in raw mode with Ioctl .. How ?

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Thu Nov 1 00:22:36 AEST 1990


In article <4214 at auspex.auspex.com> guy at auspex.auspex.com (Guy Harris) writes:
> >A much simpler way to guarantee that program X will not mess up your tty
> >modes is to run it under pty. pty is totally transparent to job control,
> >but will restore your tty modes properly on stop or exit.
> Does it restore my screen as well?  I.e., if it's a full-screen program,
> when I hit ^Z, will it either clear the screen or put the cursor at the
> bottom of the screen, and when I continue the program will it redraw the
> screen?

If that's what your program does, yes. One of my first design criteria
was that pty vi should feel *exactly* like a normal vi. (And it's
amazing how many roadblocks POSIX throws in the way of this goal.)

It's certainly not pty's responsibility to redraw the screen if your
program doesn't. Virtual terminal management does not fall under
pseudo-tty session management. If you want this feature, make it into a
separate program.

Okay, okay, I just spent a few minutes and did the work. Enclosed is
a sloppy fullscreen.c. You might invoke it as

  pty -pcE fullscreen nastyprog

nastyprog will run in a full-screen curses window, in character mode
with echo off. Terminal stop characters will affect pty rather than
going through to nastyprog. Your tty will be restored to its original
mode upon ^Z or nastyprog exit. curses will do what you asked for.

Any other requests?

> If not, I'm not interested.

What a productive attitude.

---Dan

#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include <curses.h>

#define SIZ 1024

int f;
int pi[2];
char buf[SIZ];
int r;
int i;

sigchld()
{
 union wait w;
 int x;
 int y;

 if (wait3(&w,WUNTRACED | WNOHANG,(struct rusage *) 0) <= 0)
   return;
 if (w.w_stopval == WSTOPPED)
   kill(f,SIGCONT);
 else
  {
   r = read(pi[0],buf,SIZ);
   if (r > 0)
     for (i = 0;i < r;i++)
       addch(buf[i]);
   refresh();
   move(23,0);
   refresh();
   getyx(stdscr,y,x);
   mvcur(y,x,23,0);
   endwin();
   resetty();
   exit(w.w_retcode & 127);
  }
}

main(argc,argv)
int argc;
char *argv[];
{
 signal(SIGCHLD,sigchld);
 pipe(pi);
 switch(f = fork())
  {
   case -1: break;
   case 0: close(pi[0]);
	   dup2(pi[1],1);
	   close(pi[1]);
	   execvp(argv[1],argv + 1);
	   break;
   default: close(pi[1]);
	    close(0);
	    savetty();
	    initscr();
	    refresh();
	    scrollok(stdscr,1);
	    for (;;)
	     {
	      r = read(pi[0],buf,SIZ);
	      if (r == 0)
	        break;
	      if (r > -1)
		for (i = 0;i < r;i++)
		  addch(buf[i]);
	      refresh();
	     }
	    sigpause(0);
  }
 exit(0);
}



More information about the Comp.unix.programmer mailing list