Pseudo terminal problem

garg at alpha.ces.cwru.edu garg at alpha.ces.cwru.edu
Wed Jul 27 13:51:16 AEST 1988


Hi There :
		I am developing a menu driven X window interface for gdb.
I have finished most of it. I have a separate window for debugee process's
I/O. I opened up a pseudo terminal and duped the slave side to the 
child process's stdin, stdout and stderr. After writing to the slave side,
I try to read from the parent side (master), My program gets stuck. I will
highly appreciate if some kind soul can help me out.

The related code goes as follows:		

get_pty ()
{
        int devindex, letter = 0;

        while (letter < 3)
          {
            ttydev [8] = ptydev [8] = "pqr" [letter++];
            devindex = 0;

            while (devindex < 16)
              {
                ttydev [9] = ptydev [9] = "0123456789abcdef" [devindex++];
                if ((master = open (ptydev, O_RDWR )) < 0)
                        continue;
                if ((slave = open (ttydev, O_RDWR)) < 0)
                  {
                    close(master);
                    continue;
                  }
                close(slave);
                return;
              }
          }

        fprintf (stderr, "Not enough available pty's\n");
        exit (1);
}

/*
	I call this function in the function create_inferior() before 
	the execle system call in gdb's source.
*/

/* SETS SLAVE AS THE CHILD'S CONTROL TERMINAL AND I/O CHANNEL */

set_slave_as_inferior_terminal()
{


  int cnttty;            /* control terminal fd  */
  struct sgttyb oldsg;
  struct tchars oldtc;
  struct ltchars oldltc;
  int lined;
  unsigned lmode;

/* Remove control terminal */
  cnttty = open("/dev/tty", O_RDWR);

/* Save old terminal characteristics */
  ioctl(cnttty, TIOCGETP, &oldsg);
  ioctl(cnttty, TIOCGETC, &oldtc);
  ioctl(cnttty, TIOCGLTC, &oldltc);
  ioctl(cnttty, TIOCGETD, &lined);
  ioctl(cnttty, TIOCLGET, (char *)&lmode);

/* Now remove */

  ioctl(cnttty, TIOCNOTTY, 0);
  close(cnttty);

  if((cnttty = open(ttydev, O_RDWR)) < 0)
    {
      printf(stderr, "error opening childs control terminal\n");
      exit(1);
    }

/*  chown(ttydev, getuid(), getgid());
  chmod(ttydev, 0622);

  oldsg.sg_flags & = ~(ALLDELAY | XTABS | CBREAK | RAW);
  oldsg.sg_flags | = ECHO | CRMOD;
*/

/*  Set as  old terminal characteristics  */
  
  if((ioctl(cnttty, TIOCSETP, &oldsg)) == -1)
    {
      printf(stderr, "error setting childs control terminal\n");
      exit(1);
    }

  if((ioctl(cnttty, TIOCSETC, &oldtc)) == -1)
    {
      printf(stderr, "error setting childs control terminal\n");
      exit(1);
    }

  if((ioctl(cnttty, TIOCSLTC, &oldltc)) == -1)
     {
       printf(stderr, "error setting childs control terminal\n");
       exit(1);
     }

  if((ioctl(cnttty, TIOCSETD, &lined)) == -1)
     {
       printf(stderr, "error setting childs control terminal\n");
       exit(1);
     }

  if((ioctl(cnttty, TIOCLSET, (char *)&lmode)) == -1)
     {
       printf(stderr, "error setting childs control terminal\n");
       exit(1);
     }

  /* set standard files to be the same as the control terminal */
  dup2(cnttty, 0);
  dup2(cnttty, 1);  
  dup2(cnttty, 2);

/* close the control terminal not needed any more  */

  close(cnttty);    

}

/* From gdb's command_loop() function I enter this function and after that
I will remain in this function only.
This works fine if my debugee process does not write anything and gets
stuck if the debugee process writes something on the slave side.  */

/* This is the main command loop  */

void
xgdb_dispatch (fp)             
     FILE *fp;
{
  int xmask = 1 << ConnectionNumber(XtDisplay(toplevel));
  int rfds = 0;
  int nfds;
  int pend, i;
  char buffer[64];
  int inferior_out_mask;

  get_pty();
  inferior_out_mask = 1 << master;

  while(1)
    {
      pend = XPending(XtDisplay(toplevel));
      if (!pend)
        {
          rfds =  xmask | inferior_out_mask ;
          nfds = select (32, &rfds, 0, 0, (struct timeval *) 0);
        }
      if (pend || rfds & xmask)
        {
          XNextEvent(XtDisplay(toplevel), &ev);
          XtDispatchEvent(&ev);
        }
      while(rfds & inferior_out_mask) /* !! IT SEEMS STUCK HERE */
        {
          if((i = read(master, buffer, 64)) > 0) 
            printf("%s", buffer);
          fflush(stdout);
          rfds = rfds & (~inferior_out_mask);
        }

    }
}

/* Any help will be highly appreciated.  */
usenet: {decvax,cbosgd,sun}!mandrill!garg	Dev Datt Garg
csnet:       garg at mandrill.CWRU.edu
arpa:        garg at mandrill.CWRU.edu



More information about the Comp.unix.wizards mailing list