home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xdbx / part01 / calldbx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-28  |  5.7 KB  |  196 lines

  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. /*  calldbx.c
  34.  *
  35.  *    Set up communication between dbx and xdbx using pseudo terminal, and
  36.  *    call dbx.
  37.  *
  38.  *    open_master():    Open the master side of pty.
  39.  *    open_slave():     Open the slave side of pty.
  40.  *    calldbx():     Invoke dbx.
  41.  */
  42.  
  43. #include    <termio.h>
  44. #include    "global.h"
  45.  
  46. FILE               *dbxfp = NULL;        /* file pointer to dbx */
  47. int                dbxpid = 0;        /* dbx process id */
  48.  
  49. static int    dbxInputId;        /* dbx input id */
  50. static char     pty[11] = "/dev/pty??";    /* master side of pseudo-terminal */
  51. static char     tty[11] = "/dev/tty??";    /* slave side of pseudo-terminal */
  52. extern char    *dbxprompt;
  53.  
  54. /*
  55.  *  Xdbx talks to dbx through a pseudo terminal which is a pair of master
  56.  *  and slave devices: /dev/pty?? and /dev/tty??, where ?? goes from p0 to
  57.  *  sf (system dependent).  The pty is opened for both read and write.
  58.  */
  59. static int open_master()
  60. {
  61.     int  i, master; 
  62.     char c;
  63.  
  64.     for (c='p'; c<='s'; c++) {
  65.     pty[8] = c;
  66.     for (i=0; i<16; i++) {
  67.         pty[9] = "0123456789abcdef"[i];
  68.         if ((master = open(pty, O_RDWR)) != -1) 
  69.         return (master); 
  70.     }
  71.     }
  72.     fprintf(stderr, "xdbx: all ptys in use\n");
  73.     exit(1);
  74. }
  75.  
  76. static int open_slave()
  77. {
  78.     int slave;
  79.  
  80.     tty[8] = pty[8];
  81.     tty[9] = pty[9];
  82.     if ((slave = open(tty, O_RDWR)) != -1)
  83.     return (slave);
  84.     fprintf(stderr, "open: cannot open slave pty %s", tty);
  85.     exit(1);
  86. }
  87.  
  88. /* ARGSUSED */
  89. void calldbx(argc, argv)
  90. int argc;
  91. char *argv[];
  92. {
  93.     struct termio Termio;
  94.     int        master;        /* file descriptor of master pty */
  95.     int        slave;         /* file descriptor of slave pty */
  96.     int          fd;             /* file descriptor of controlling tty */
  97.     int          pid;            /* process id */
  98.     int          pgrp;            /* process group id */
  99.     char       *debugger;         /* name of executable debugger */
  100.     char      errmsg[LINESIZ];
  101.  
  102.     debugger = (char *) getenv("DEBUGGER");    /* first looks up env var */
  103.     if (debugger == NULL)
  104.     debugger = XtNewString(DEBUGGER);
  105.   
  106.     /* construct dbx prompt string based on the name of debugger invoked */
  107.     if (dbxprompt == NULL) {
  108.     dbxprompt = XtMalloc((4+strlen(debugger)) * sizeof(char));
  109.     sprintf(dbxprompt, "(%s) ", debugger);
  110.     }
  111.   
  112.     /*
  113.      * Clear controlling tty.  Do this now, so that open_slave and
  114.      * open_master will cause the selected pty to become the
  115.      * controlling tty.
  116.      */
  117.     if ((fd = open("/dev/tty", O_RDWR)) > 0) {
  118.     ioctl(fd, TIOCNOTTY, 0);
  119.     close(fd);
  120.     }
  121.  
  122.     master = open_master();
  123.     slave = open_slave();
  124.  
  125.     dbxpid = fork();
  126.     if (dbxpid == -1) {
  127.     perror("xdbx error: cannot fork process");
  128.     exit(1);
  129.     }
  130.     else if (dbxpid) { 
  131.     /* 
  132.      * Parent : close the slave side of pty
  133.      *        close stdin and stdout
  134.      *        set the dbx file descriptor to nonblocking mode
  135.      *        open file pointer with read/write access to dbx
  136.      *        set line buffered mode
  137.      *        register dbx input with X
  138.      */
  139.     close(slave);
  140.     close(0);
  141.     close(1);
  142.     fcntl(master, F_SETFL, FNDELAY);
  143.         dbxfp = fdopen(master, "r+");
  144.     setlinebuf(dbxfp);
  145.     dbxInputId = XtAppAddInput(app_context, master, XtInputReadMask, 
  146.                    read_dbx, NULL);
  147.     }
  148.     else { 
  149.     /* 
  150.      * Child : close master side of pty
  151.      *        redirect stdin, stdout, stderr of dbx to pty
  152.      *       unbuffer output data from dbx
  153.      *       exec dbx with arguments
  154.      */
  155.     close(master);
  156.  
  157.     /*
  158.      * Modify local and output mode of slave pty
  159.      */
  160.     ioctl(slave, TCGETA, &Termio);
  161.     Termio.c_lflag &= ~ECHO;    /* No echo */
  162.     Termio.c_oflag &= ~ONLCR;    /* Do not map NL to CR-NL on output */
  163.     ioctl(slave, TCSETA, &Termio);
  164.  
  165.     dup2(slave, 0);
  166.     dup2(slave, 1);
  167.     dup2(slave, 2);
  168.     if (slave > 2)
  169.         close(slave);
  170.     fcntl(1, F_SETFL, FAPPEND);
  171.     setbuf(stdout, NULL);
  172.  
  173.     /*
  174.      * Set our process group to that of the terminal,
  175.      * so we can change the group of the terminal.
  176.      */
  177.     ioctl(0, TIOCGPGRP, &pgrp);
  178.     setpgrp(0, pgrp);
  179.  
  180.     /*
  181.      * Now set the process group of the terminal and of us
  182.      * to our process id.  This clears us from the control
  183.      * of the other process group.
  184.      */
  185.     pid = getpid();
  186.     ioctl(0, TIOCSPGRP, &pid);
  187.     setpgrp(0, pid);
  188.  
  189.     argv[0] = debugger;
  190.     execvp(debugger, argv);
  191.     sprintf(errmsg, "xdbx error: cannot exec %s", debugger);
  192.     perror(errmsg);
  193.     exit(1);
  194.     }
  195. }
  196.