"Fossies" - the Fresh Open Source Software Archive

Member "xxgdb-1.12/calldbx.c" (19 Jun 1995, 11345 Bytes) of package /linux/misc/old/xxgdb-1.12.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /*****************************************************************************
    2  *
    3  *  xdbx - X Window System interface to the dbx debugger
    4  *
    5  *  Copyright 1989 The University of Texas at Austin
    6  *  Copyright 1990 Microelectronics and Computer Technology Corporation
    7  *
    8  *  Permission to use, copy, modify, and distribute this software and its
    9  *  documentation for any purpose and without fee is hereby granted,
   10  *  provided that the above copyright notice appear in all copies and that
   11  *  both that copyright notice and this permission notice appear in
   12  *  supporting documentation, and that the name of The University of Texas
   13  *  and Microelectronics and Computer Technology Corporation (MCC) not be 
   14  *  used in advertising or publicity pertaining to distribution of
   15  *  the software without specific, written prior permission.  The
   16  *  University of Texas and MCC makes no representations about the 
   17  *  suitability of this software for any purpose.  It is provided "as is" 
   18  *  without express or implied warranty.
   19  *
   20  *  THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
   21  *  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
   22  *  FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
   23  *  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
   24  *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
   25  *  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
   26  *  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   27  *
   28  *  Author:     Po Cheung
   29  *  Created:    March 10, 1989
   30  *
   31  *****************************************************************************
   32  * 
   33  *  xxgdb - X Window System interface to the gdb debugger
   34  *  
   35  *  Copyright 1990,1993 Thomson Consumer Electronics, Inc.
   36  *  
   37  *  Permission to use, copy, modify, and distribute this software and its
   38  *  documentation for any purpose and without fee is hereby granted,
   39  *  provided that the above copyright notice appear in all copies and that
   40  *  both that copyright notice and this permission notice appear in
   41  *  supporting documentation, and that the name of Thomson Consumer
   42  *  Electronics (TCE) not be used in advertising or publicity pertaining
   43  *  to distribution of the software without specific, written prior
   44  *  permission.  TCE makes no representations about the suitability of
   45  *  this software for any purpose.  It is provided "as is" without express
   46  *  or implied warranty.
   47  *
   48  *  TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   49  *  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
   50  *  SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
   51  *  OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   52  *  WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   53  *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   54  *  SOFTWARE.
   55  *
   56  *  Adaptation to GDB:  Pierre Willard
   57  *  XXGDB Created:      December, 1990
   58  *
   59  *****************************************************************************/
   60 
   61 /*  calldbx.c
   62  *
   63  *    Set up communication between dbx and xdbx using pseudo terminal, and
   64  *    call dbx.
   65  *
   66  *    open_master():    Open the master side of pty.
   67  *    open_slave():     Open the slave side of pty.
   68  *    calldbx():    Invoke dbx.
   69  *    create_io_window(): create an io window for gdb to use 
   70  */
   71 
   72 #include <stdio.h>
   73 #include <stdlib.h>
   74 #include <string.h>
   75 #include <fcntl.h>
   76 #include "global.h"
   77 #if !(defined(OLDSUNOS) || defined(BSD))
   78 #include <termio.h>
   79 #else
   80 #include <sgtty.h>
   81 #endif
   82 
   83 #ifdef CREATE_IO_WINDOW
   84 #include    <sys/socket.h>
   85 #include        <sys/un.h>
   86 #endif /* CREATE_IO_WINDOW */
   87 
   88 #ifdef SVR4
   89 #define MASTER_CLONE "/dev/ptmx"
   90 #include <sys/types.h>
   91 #include <sys/stat.h>
   92 #include <sys/stropts.h>
   93 #include <signal.h>
   94 #endif /* SVR4 */
   95 
   96 #if (defined(BSD) && (BSD < 44)) || defined(ultrix)
   97 #define OLDBSD
   98 #endif
   99 #if defined(TIOCSCTTY)
  100 #define NEWBSD
  101 #endif
  102 
  103 extern char *progname;      /* (MJH) */
  104 
  105 FILE            *dbxfp = NULL;      /* file pointer to dbx */
  106 int             dbxpid = 0;     /* dbx process id */
  107 
  108 static XtInputId    dbxInputId;     /* dbx input id */
  109 #ifndef SVR4                /* (MJH) */
  110 static char     pty[11] = "/dev/pty??"; /* master side of pseudo-terminal */
  111 static char     tty[11] = "/dev/tty??"; /* slave side of pseudo-terminal */
  112 #endif /* SVR4 */
  113 extern char *dbxprompt;
  114 
  115 #ifdef CREATE_IO_WINDOW
  116 char            iowintty[] = "/dev/ttyp0";
  117 int             iowinpid = 0;
  118 #endif /* CREATE_IO_WINDOW */
  119 /*
  120  *  Xdbx talks to dbx through a pseudo terminal which is a pair of master
  121  *  and slave devices: /dev/pty?? and /dev/tty??, where ?? goes from p0 to
  122  *  sf (system dependent).  The pty is opened for both read and write.
  123  */
  124 static int open_master()
  125 {
  126     int master;
  127     
  128 #ifdef SVR4             /* (MJH) Use STREAMS */
  129 
  130     if((master = open(MASTER_CLONE, O_RDWR)) < 0)
  131     perror(MASTER_CLONE);
  132     else
  133     return master;
  134 #else
  135     int  i;
  136     char c;
  137 
  138 #ifndef sco
  139     for (c='p'; c<'t'; c++) {
  140     for (i=0; i<16; i++) {
  141 #else
  142     c = 'p';
  143     for (i=0; i<8; i++) {
  144 #endif
  145         pty[8] = c;
  146         pty[9] = "0123456789abcdef"[i];
  147         if ((master = open(pty, O_RDWR)) >= 0) 
  148         return (master); 
  149     }
  150 #ifndef sco
  151     }
  152 #endif
  153 #endif /* SVR4 */
  154 
  155 #ifdef GDB
  156     fprintf(stderr, "xxgdb: all ptys in use\n");
  157 #else
  158     fprintf(stderr, "xdbx: all ptys in use\n");
  159 #endif
  160     exit(1);
  161 }
  162 
  163 /*ARGSUSED*/
  164 static int open_slave(master)
  165     int master;
  166 {
  167     int slave;
  168 
  169 #ifdef SVR4             /* (MJH) */
  170     char *slave_name = "unknown";
  171     extern char *ptsname(int master);
  172     void (*handler)();
  173 
  174     if(((handler = signal(SIGCHLD, SIG_DFL)) != SIG_ERR) &&
  175        (grantpt(master) == 0) &&
  176        (signal(SIGCHLD, handler) == SIG_DFL) &&
  177        (unlockpt(master) == 0) &&
  178        ((slave_name = ptsname(master)) != NULL) &&
  179        ((slave = open(slave_name, O_RDWR)) >= 0) &&
  180        (ioctl(slave, I_PUSH, "ptem") >= 0) &&
  181        (ioctl(slave, I_PUSH, "ldterm") >= 0))
  182     return slave;
  183     perror("Pseudo-tty slave");
  184     fprintf(stderr, "open: cannot open slave pty %s", slave_name);
  185     exit(1);
  186 #else
  187     tty[8] = pty[8];
  188     tty[9] = pty[9];
  189     if ((slave = open(tty, O_RDWR)) < 0)
  190         {
  191         perror(tty);
  192         exit(1);
  193         }
  194     return slave;
  195 #endif /* SVR4 */
  196 }
  197 
  198 #ifdef CREATE_IO_WINDOW 
  199 /* use a separate io window to talk to gdb, so program output is not confused with gdb output. */
  200 /* creates an io window which is the program xxgdbiowin running behind an 
  201  * xterm.  This function sets two global variables:
  202  * iowintty, a character array which is the resulting ptty of the xterm
  203  * iowinpid, an int which is the pid of xxgdbiowin
  204  */
  205 void
  206 create_io_window ()
  207 {
  208     int pid = fork();
  209     if (pid == -1)
  210     {
  211     printf("unable to fork\n");
  212     }
  213     else if (pid)
  214     {   /* parent */
  215     char ttypid[40];
  216     int sock;
  217     struct sockaddr_un name;
  218 
  219     sock = socket(AF_UNIX, SOCK_DGRAM, 0);
  220     name.sun_family = AF_UNIX;
  221     strcpy(name.sun_path, "/tmp/iowindowtty");
  222     bind(sock, (struct sockaddr*)&name, sizeof(struct sockaddr_un));
  223     read(sock, ttypid, 40);
  224     sscanf(ttypid, "%[a-z/0-9],%d", iowintty, &iowinpid);
  225     close(sock);
  226     unlink("/tmp/iowindowtty");
  227     }
  228     else
  229     {
  230     /* child */
  231     /* printf("xterm xterm -l -e xxgdbiowin\n");*/
  232     if (execlp("xterm", "xterm", "-e", "xxgdbiowin", 0))
  233     {
  234         printf("exec of 'xterm -e xxgdbiowin' fails\n");
  235         unlink("/tmp/iowindowtty");
  236     }
  237     }
  238 }
  239 #endif /* CREATE_IO_WINDOW */
  240 
  241 /* ARGSUSED */
  242 void calldbx(argc, argv)
  243 int argc;
  244 char *argv[];
  245 {
  246 /*
  247  * (JBL)10MAY91 : use sgttyb if generic BSD
  248  */
  249 #if !(defined(OLDSUNOS) || defined(BSD))
  250     struct termio Termio;
  251 #else
  252     struct sgttyb Termio;
  253 #endif
  254     int       master;       /* file descriptor of master pty */
  255     int       slave;        /* file descriptor of slave pty */
  256 #ifdef OLDBSD
  257     int       fd;           /* file descriptor of controlling tty */
  258 #endif
  259     char      *debugger;        /* name of executable debugger */
  260     char      errmsg[LINESIZ];
  261 
  262 #ifdef GDB  /* for GDB, we use XXGDB_DEBUGGER instead */
  263     debugger = (char *) getenv("XXGDB_DEBUGGER");   /* first looks up env var */
  264 #else
  265     debugger = (char *) getenv("DEBUGGER"); /* first looks up env var */
  266 #endif
  267 
  268 /* CRL mod 4 3/15/91 GWC if no env var then try app res for db_name */
  269     if (debugger == NULL &&
  270     app_resources.db_name &&
  271     strcmp(app_resources.db_name, "") != 0)
  272     debugger =  XtNewString(app_resources.db_name);
  273       
  274     if (debugger == NULL)
  275     debugger  = XtNewString(DEBUGGER);
  276 
  277 /* CRL mod 4 3/15/91 GWC -  allow the user to specify a db_prompt */
  278     if (app_resources.db_prompt &&
  279     strcmp(app_resources.db_prompt, "") != 0)
  280     dbxprompt = XtNewString(app_resources.db_prompt);
  281   
  282     /* construct dbx prompt string based on the name of debugger invoked */
  283     if (dbxprompt == NULL) {
  284     dbxprompt = XtMalloc((4+strlen(debugger)) * sizeof(char));
  285     sprintf(dbxprompt, "(%s) ", debugger);
  286     }
  287     
  288     if (debug)
  289         fprintf(stderr,"debugger=\"%s\"\nprompt=\"%s\"\n",debugger,dbxprompt);
  290   
  291     master = open_master();
  292 
  293     dbxpid = fork();
  294     if (dbxpid == -1) {
  295     sprintf(errmsg, "%s error: Cannot fork %s\n", progname, debugger);  /* (MJH) */
  296     perror(errmsg);
  297     exit(1);
  298     }
  299     else if (dbxpid) { 
  300     /* 
  301      * Parent : close the slave side of pty
  302      *      close stdin and stdout
  303      *      set the dbx file descriptor to nonblocking mode
  304      *      open file pointer with read/write access to dbx
  305      *      set line buffered mode
  306      *      register dbx input with X
  307      */
  308     close(0);
  309     close(1);
  310 
  311 #ifdef _POSIX_SOURCE
  312     fcntl(master, F_SETFL, O_NONBLOCK);
  313 #else
  314     fcntl(master, F_SETFL, O_NDELAY);
  315 #endif
  316     
  317     if((dbxfp = fdopen(master, "r+")) == NULL)  /* (MJH) */
  318     {
  319         perror("Associating stdio stream with pty master");
  320         exit(1);
  321     }
  322     
  323     /*  turn off stdio buffering  */
  324     setbuf(dbxfp, NULL);
  325 
  326     dbxInputId = XtAppAddInput(app_context, master, (XtPointer) XtInputReadMask, 
  327                    read_dbx, NULL);
  328     }
  329     else { 
  330     /* 
  331      * Child : close master side of pty
  332      *     redirect stdin, stdout, stderr of dbx to pty
  333      *     unbuffer output data from dbx
  334      *     exec dbx with arguments
  335      */
  336 
  337     /* lose controlling tty */
  338 #if defined(NEWBSD) || defined(SVR4) || defined(_POSIX_SOURCE)
  339     setsid();
  340 #endif
  341 #ifdef OLDBSD
  342     if ((fd = open("/dev/tty", O_RDWR)) > 0) {
  343         ioctl(fd, TIOCNOTTY, 0);
  344         close(fd);
  345     }
  346 #endif
  347 
  348     slave = open_slave(master);
  349     close(master);
  350 
  351     /*
  352      * Modify local and output mode of slave pty
  353      */
  354      
  355     /*
  356      * (JBL)10MAY91 : use sgttyb if OLDSUN or generic BSD
  357      */ 
  358 #if !(defined(OLDSUNOS) || defined(BSD))
  359     ioctl(slave, TCGETA, &Termio);
  360     Termio.c_lflag &= ~ECHO;    /* No echo */
  361     Termio.c_oflag &= ~ONLCR;   /* Do not map NL to CR-NL on output */
  362     ioctl(slave, TCSETA, &Termio);
  363 #else
  364     ioctl(slave, TIOCGETP, &Termio);
  365     Termio.sg_flags &= ~ECHO;   /* No echo */
  366     Termio.sg_flags &= ~CRMOD;  /* Do not map NL to CR-NL on output */
  367     ioctl(slave, TIOCSETP, &Termio);
  368 #endif
  369 
  370     dup2(slave, 0);
  371     dup2(slave, 1);
  372     dup2(slave, 2);
  373     if (slave > 2)
  374         close(slave);
  375         
  376     fcntl(1, F_SETFL, O_APPEND);
  377     setbuf(stdout, NULL);
  378 
  379     /* gain controlling tty */
  380 #ifdef NEWBSD
  381     ioctl(0, TIOCSCTTY, 0);
  382 #endif
  383 
  384     /* flush stdin ! (for RS6000)  FIXME */
  385 
  386     argv[0] = debugger;
  387 
  388     if (debug) {
  389         int i=0;
  390         fprintf (stderr, "Forking \"%s",argv[i++]);
  391         while (argv[i]) {
  392             fprintf (stderr, " %s", argv[i++]);
  393         }
  394         fprintf (stderr, "\"\n");
  395     }
  396 
  397     execvp(debugger, argv);
  398     sprintf(errmsg, "%s error: cannot exec %s", progname, debugger);
  399     perror(errmsg);
  400     exit(1);
  401     }
  402 }