Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!mailrus!tut.cis.ohio-state.edu!cwjcc!mandrill!alpha.ces.cwru.edu!garg From: garg@alpha.ces.cwru.edu Newsgroups: comp.unix.wizards Subject: Pseudo terminal problem Message-ID: <2543@mandrill.CWRU.Edu> Date: 27 Jul 88 03:51:16 GMT Sender: news@mandrill.CWRU.Edu Reply-To: garg@alpha.ces.cwru.edu () Organization: CWRU Dept of Computer Engineering and Science Lines: 175 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@mandrill.CWRU.edu arpa: garg@mandrill.CWRU.edu