"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 }