This is the mail archive of the gdb@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Driving gdb from a front end: how to send ctrl-c?


Hello,
I'm writing a front end for gdb that needs to work on
Cygwin and Linux. I'm trying out Cygwin first. After
reading several posts in the archives of this ML I
came up with a small proof-of-concept program that:
- sets up master and slave PTY
- forks a process and executes gdb in it
- sends a few commands to gdb

Everything works ok except ctrl-c. Here is the
sequence of commands my program is sending gdb:
- b main
- r
- c 
- ctrl-c (ASCII char 3)

I can see the proper output for all commands except
ctrl-c. I guess this is because I missed some terminal
settings.

The other problem is that I get about 10 msgs like
this:
[tcsetpgrp failed in terminal_inferior: Operation not
permitted]

I attached the small cygwin program I talked about.
Any help will be very much appreciated.

Marco



#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/syslimits.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pty.h>
#include <termios.h>

#define MAX_BUF_SIZE 2048

int
main (int argc, char *argv[])
{
  pid_t pid;
  size_t c;
  fd_set readfds;
  int master, slave, i;
  struct termios tt;
  struct termios rtt;

  char buf[MAX_BUF_SIZE];
  char *execargs[3] = {"/bin/gdb.exe", "./test.exe",
0};
  char ctrl_c[2] = {3, '\n'};
  struct timeval tv = {5, 000000};

  master = open ("/dev/ptmx", O_RDWR);
  if (master < 0) {
    perror ("Couldn't open master");
    exit( 1 );
  }
  (void) tcgetattr(0, &tt);
  grantpt(master);
  unlockpt(master);
  slave = open (ptsname(master), O_RDWR | O_NOCTTY);  

  if (slave < 0) {
    perror("Couldn't open slave");
    exit (1);
  }
  rtt = tt;
  rtt.c_iflag |= BRKINT;
  rtt.c_lflag |= ISIG;
  rtt.c_cflag |= CS8;
  
  (void) tcsetattr(0, TCSAFLUSH, &rtt);

  i = fork ();
  if (i < 0) {
    perror ("Couldn't fork");
    exit (1);
  }
  if (i == 0) {
    printf( "Entering child...\n" );
    if (close (master) < 0) {
      perror( "Couldn't close master");
      exit (1);
    }

    for (i = 0; i < 3; i++) {
      if (close (i) < 0) {
        perror ("close in child");
        exit (1);
      }
    }

    for (i = 0; i < 3; i++) {
      if (dup2 (slave, i) < 0) {
        perror ("dup2 in child");
        exit (1);
      }
    }

    (void) tcsetattr(slave, TCSAFLUSH, &tt);

    if (setsid () == -1) {
      perror ("setsid()");
      exit (1);
    }

    close (slave);

    if (execvp ("/bin/gdb.exe", execargs) < 0) {
      perror (execargs[0]);
      exit (1);
    }

    _exit( -43 );

  }

  printf ("In parent.\n");
  close (slave);
  FD_ZERO (&readfds);

  write (master, "b main\n", 7);
  write (master, "r\n", 2);
  write (master, "c\n", 2);
  select (master + 1, NULL, NULL, NULL, &tv);
  write (master, ctrl_c, 2);

  while (1) {
    c = read( master, buf, MAX_BUF_SIZE );
    write (1, buf, c);
  }

  pid = wait( NULL );
  printf( "child with pid %d finished.\n", pid );

  exit( 0 );
}


__________________________________
Do you Yahoo!?
Yahoo! Mail - More reliable, more storage, less spam
http://mail.yahoo.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]