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