Fri Dec 6 23:57:34 1991 K. Richard Pixley (rich at rtl.cygnus.com)
[deliverable/binutils-gdb.git] / gdb / inflow.c
CommitLineData
bd5635a1
RP
1/* Low level interface to ptrace, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
715d2e06 6This program is free software; you can redistribute it and/or modify
bd5635a1 7it under the terms of the GNU General Public License as published by
715d2e06
JG
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
bd5635a1 10
715d2e06 11This program is distributed in the hope that it will be useful,
bd5635a1
RP
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
715d2e06
JG
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
bd5635a1
RP
19
20#include <stdio.h>
21#include "defs.h"
bd5635a1
RP
22#include "frame.h"
23#include "inferior.h"
24#include "command.h"
25#include "signals.h"
26#include "terminal.h"
27#include "target.h"
28
29#ifdef USG
30#include <sys/types.h>
31#endif
32
33/* Some USG-esque systems (some of which are BSD-esque enough so that USG
34 is not defined) want this header, and it won't do any harm. */
35#include <fcntl.h>
36
37#include <sys/param.h>
38#include <sys/dir.h>
39#include <signal.h>
40
2a5ec41d
JG
41extern char *strerror(); /* strings corresponding to errno */
42
bd5635a1
RP
43extern struct target_ops child_ops;
44
45/* Nonzero if we are debugging an attached outside process
46 rather than an inferior. */
47
48int attach_flag;
49
50\f
51/* Record terminal status separately for debugger and inferior. */
52
2a5ec41d
JG
53/* Does GDB have a terminal (on stdin)? */
54int gdb_has_a_terminal;
55
bd5635a1
RP
56static TERMINAL sg_inferior;
57static TERMINAL sg_ours;
58
59static int tflags_inferior;
60static int tflags_ours;
61
62#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
63static struct tchars tc_inferior;
64static struct tchars tc_ours;
65#endif
66
7d9884b9 67#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
bd5635a1
RP
68static struct ltchars ltc_inferior;
69static struct ltchars ltc_ours;
70#endif
71
72#ifdef TIOCLGET
73static int lmode_inferior;
74static int lmode_ours;
75#endif
76
77#ifdef TIOCGPGRP
7d9884b9
JG
78# ifdef SHORT_PGRP
79static short pgrp_inferior;
80static short pgrp_ours;
81# else
bd5635a1
RP
82static int pgrp_inferior;
83static int pgrp_ours;
7d9884b9 84# endif
bd5635a1
RP
85#else
86static void (*sigint_ours) ();
87static void (*sigquit_ours) ();
88#endif /* TIOCGPGRP */
89
2a5ec41d
JG
90/* The name of the tty (from the `tty' command) that we gave to the inferior
91 when it was last started. */
bd5635a1 92
2a5ec41d 93static char *inferior_thisrun_terminal;
bd5635a1
RP
94
95/* Nonzero if our terminal settings are in effect.
96 Zero if the inferior's settings are in effect. */
2a5ec41d 97
bd5635a1
RP
98static int terminal_is_ours;
99
2a5ec41d
JG
100/* Macro for printing errors from ioctl operations */
101
102#define OOPSY(what) \
103 if (result == -1) \
104 fprintf(stderr, "[%s failed in terminal_inferior: %s]\n", \
105 what, strerror (errno))
106
107static void terminal_ours_1 ();
108
bd5635a1
RP
109/* Initialize the terminal settings we record for the inferior,
110 before we actually run the inferior. */
111
112void
113terminal_init_inferior ()
114{
115 sg_inferior = sg_ours;
116 tflags_inferior = tflags_ours;
117
118#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
119 tc_inferior = tc_ours;
120#endif
121
7d9884b9 122#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
bd5635a1
RP
123 ltc_inferior = ltc_ours;
124#endif
125
126#ifdef TIOCLGET
127 lmode_inferior = lmode_ours;
128#endif
129
130#ifdef TIOCGPGRP
131 pgrp_inferior = inferior_pid;
132#endif /* TIOCGPGRP */
133
134 terminal_is_ours = 1;
135}
136
137/* Put the inferior's terminal settings into effect.
138 This is preparation for starting or resuming the inferior. */
139
140void
141terminal_inferior ()
142{
2a5ec41d
JG
143 int result;
144
145 if (gdb_has_a_terminal && terminal_is_ours && inferior_thisrun_terminal == 0)
bd5635a1 146 {
2a5ec41d
JG
147 result = fcntl (0, F_SETFL, tflags_inferior);
148 result = fcntl (0, F_SETFL, tflags_inferior);
149 OOPSY ("fcntl F_SETFL");
150 result = ioctl (0, TIOCSETN, &sg_inferior);
151 OOPSY ("ioctl TIOCSETN");
bd5635a1
RP
152
153#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
2a5ec41d
JG
154 result = ioctl (0, TIOCSETC, &tc_inferior);
155 OOPSY ("ioctl TIOCSETC");
bd5635a1 156#endif
7d9884b9 157#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
2a5ec41d
JG
158 result = ioctl (0, TIOCSLTC, &ltc_inferior);
159 OOPSY ("ioctl TIOCSLTC");
bd5635a1
RP
160#endif
161#ifdef TIOCLGET
2a5ec41d
JG
162 result = ioctl (0, TIOCLSET, &lmode_inferior);
163 OOPSY ("ioctl TIOCLSET");
bd5635a1
RP
164#endif
165
166#ifdef TIOCGPGRP
2a5ec41d
JG
167 result = ioctl (0, TIOCSPGRP, &pgrp_inferior);
168 OOPSY ("ioctl TIOCSPGRP");
bd5635a1
RP
169#else
170 sigint_ours = (void (*) ()) signal (SIGINT, SIG_IGN);
171 sigquit_ours = (void (*) ()) signal (SIGQUIT, SIG_IGN);
172#endif /* TIOCGPGRP */
173 }
174 terminal_is_ours = 0;
175}
176
177/* Put some of our terminal settings into effect,
178 enough to get proper results from our output,
179 but do not change into or out of RAW mode
180 so that no input is discarded.
181
182 After doing this, either terminal_ours or terminal_inferior
183 should be called to get back to a normal state of affairs. */
184
185void
186terminal_ours_for_output ()
187{
188 terminal_ours_1 (1);
189}
190
191/* Put our terminal settings into effect.
192 First record the inferior's terminal settings
193 so they can be restored properly later. */
194
195void
196terminal_ours ()
197{
198 terminal_ours_1 (0);
199}
200
201static void
202terminal_ours_1 (output_only)
203 int output_only;
204{
2a5ec41d 205 int result;
bd5635a1
RP
206#ifdef TIOCGPGRP
207 /* Ignore this signal since it will happen when we try to set the pgrp. */
208 void (*osigttou) ();
209#endif /* TIOCGPGRP */
210
2a5ec41d 211 /* Checking inferior_thisrun_terminal is necessary so that
bd5635a1 212 if GDB is running in the background, it won't block trying
2a5ec41d
JG
213 to do the ioctl()'s below. Checking gdb_has_a_terminal
214 avoids attempting all the ioctl's when running in batch. */
215 if (inferior_thisrun_terminal != 0 || gdb_has_a_terminal == 0)
bd5635a1
RP
216 return;
217
218 if (!terminal_is_ours)
219 {
220 terminal_is_ours = 1;
221
222#ifdef TIOCGPGRP
223 osigttou = (void (*) ()) signal (SIGTTOU, SIG_IGN);
224
2a5ec41d
JG
225 result = ioctl (0, TIOCGPGRP, &pgrp_inferior);
226 result = ioctl (0, TIOCSPGRP, &pgrp_ours);
bd5635a1
RP
227
228 signal (SIGTTOU, osigttou);
229#else
230 signal (SIGINT, sigint_ours);
231 signal (SIGQUIT, sigquit_ours);
232#endif /* TIOCGPGRP */
233
234 tflags_inferior = fcntl (0, F_GETFL, 0);
2a5ec41d 235 result = ioctl (0, TIOCGETP, &sg_inferior);
bd5635a1
RP
236
237#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
2a5ec41d 238 result = ioctl (0, TIOCGETC, &tc_inferior);
bd5635a1 239#endif
7d9884b9 240#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
2a5ec41d 241 result = ioctl (0, TIOCGLTC, &ltc_inferior);
bd5635a1
RP
242#endif
243#ifdef TIOCLGET
2a5ec41d 244 result = ioctl (0, TIOCLGET, &lmode_inferior);
bd5635a1
RP
245#endif
246 }
247
248#ifdef HAVE_TERMIO
249 sg_ours.c_lflag |= ICANON;
250 if (output_only && !(sg_inferior.c_lflag & ICANON))
251 sg_ours.c_lflag &= ~ICANON;
252#else /* not HAVE_TERMIO */
253 sg_ours.sg_flags &= ~RAW & ~CBREAK;
254 if (output_only)
255 sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
256#endif /* not HAVE_TERMIO */
257
2a5ec41d
JG
258 result = fcntl (0, F_SETFL, tflags_ours);
259 result = fcntl (0, F_SETFL, tflags_ours);
260 result = ioctl (0, TIOCSETN, &sg_ours);
bd5635a1
RP
261
262#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
2a5ec41d 263 result = ioctl (0, TIOCSETC, &tc_ours);
bd5635a1 264#endif
7d9884b9 265#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
2a5ec41d 266 result = ioctl (0, TIOCSLTC, &ltc_ours);
bd5635a1
RP
267#endif
268#ifdef TIOCLGET
2a5ec41d 269 result = ioctl (0, TIOCLSET, &lmode_ours);
bd5635a1
RP
270#endif
271
272#ifdef HAVE_TERMIO
273 sg_ours.c_lflag |= ICANON;
274#else /* not HAVE_TERMIO */
275 sg_ours.sg_flags &= ~RAW & ~CBREAK;
276#endif /* not HAVE_TERMIO */
277}
278
279/* ARGSUSED */
280void
281term_info (arg, from_tty)
282 char *arg;
283 int from_tty;
284{
285 target_terminal_info (arg, from_tty);
286}
287
715d2e06 288/* ARGSUSED */
bd5635a1
RP
289void
290child_terminal_info (args, from_tty)
291 char *args;
292 int from_tty;
293{
294 register int i;
295
2a5ec41d
JG
296 if (!gdb_has_a_terminal) {
297 printf_filtered ("This GDB does not control a terminal.\n");
298 return;
299 }
300
bd5635a1
RP
301 printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
302
2a5ec41d
JG
303 printf_filtered ("owner pgrp = %d, fcntl flags = 0x%x.\n",
304 pgrp_inferior, tflags_inferior);
305
bd5635a1
RP
306#ifdef HAVE_TERMIO
307
817b8c46 308 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
2a5ec41d 309 sg_inferior.c_iflag, sg_inferior.c_oflag);
bd5635a1
RP
310 printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
311 sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
312 printf_filtered ("c_cc: ");
313 for (i = 0; (i < NCC); i += 1)
314 printf_filtered ("0x%x ", sg_inferior.c_cc[i]);
315 printf_filtered ("\n");
316
317#else /* not HAVE_TERMIO */
318
2a5ec41d 319 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", sg_inferior.sg_flags);
bd5635a1
RP
320
321#endif /* not HAVE_TERMIO */
322
323#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
324 printf_filtered ("tchars: ");
325 for (i = 0; i < (int)sizeof (struct tchars); i++)
2a5ec41d 326 printf_filtered ("0x%x ", ((unsigned char *)&tc_inferior)[i]);
bd5635a1
RP
327 printf_filtered ("\n");
328#endif
329
7d9884b9 330#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
bd5635a1
RP
331 printf_filtered ("ltchars: ");
332 for (i = 0; i < (int)sizeof (struct ltchars); i++)
2a5ec41d 333 printf_filtered ("0x%x ", ((unsigned char *)&ltc_inferior)[i]);
bd5635a1
RP
334 printf_filtered ("\n");
335#endif
336
337#ifdef TIOCLGET
338 printf_filtered ("lmode: 0x%x\n", lmode_inferior);
339#endif
340}
341\f
715d2e06
JG
342/* NEW_TTY_PREFORK is called before forking a new child process,
343 so we can record the state of ttys in the child to be formed.
344 TTYNAME is null if we are to share the terminal with gdb;
345 or points to a string containing the name of the desired tty.
bd5635a1 346
715d2e06
JG
347 NEW_TTY is called in new child processes under Unix, which will
348 become debugger target processes. This actually switches to
349 the terminal specified in the NEW_TTY_PREFORK call. */
350
7d9884b9 351void
715d2e06 352new_tty_prefork (ttyname)
bd5635a1
RP
353 char *ttyname;
354{
bd5635a1
RP
355 /* Save the name for later, for determining whether we and the child
356 are sharing a tty. */
357 inferior_thisrun_terminal = ttyname;
715d2e06
JG
358}
359
360void
361new_tty ()
362{
363 register int tty;
364
365 if (inferior_thisrun_terminal == 0)
bd5635a1
RP
366 return;
367
368#ifdef TIOCNOTTY
369 /* Disconnect the child process from our controlling terminal. */
370 tty = open("/dev/tty", O_RDWR);
371 if (tty > 0)
372 {
373 ioctl(tty, TIOCNOTTY, 0);
374 close(tty);
375 }
376#endif
377
378 /* Now open the specified new terminal. */
379
7d9884b9
JG
380#ifdef USE_O_NOCTTY
381 tty = open(inferior_thisrun_terminal, O_RDWR | O_NOCTTY);
382#else
715d2e06 383 tty = open(inferior_thisrun_terminal, O_RDWR);
7d9884b9 384#endif
bd5635a1
RP
385 if (tty == -1)
386 {
715d2e06 387 print_sys_errmsg (inferior_thisrun_terminal, errno);
bd5635a1
RP
388 _exit(1);
389 }
390
391 /* Avoid use of dup2; doesn't exist on all systems. */
392 if (tty != 0)
393 { close (0); dup (tty); }
394 if (tty != 1)
395 { close (1); dup (tty); }
396 if (tty != 2)
397 { close (2); dup (tty); }
398 if (tty > 2)
399 close(tty);
400}
401\f
402/* Kill the inferior process. Make us have no inferior. */
403
404/* ARGSUSED */
405static void
406kill_command (arg, from_tty)
407 char *arg;
408 int from_tty;
409{
410 if (inferior_pid == 0)
411 error ("The program is not being run.");
412 if (!query ("Kill the inferior process? "))
413 error ("Not confirmed.");
414 target_kill (arg, from_tty);
777bef06
JK
415
416 /* Killing off the inferior can leave us with a core file. If so,
417 print the state we are left in. */
418 if (target_has_stack) {
419 printf_filtered ("In %s,\n", current_target->to_longname);
420 if (selected_frame == NULL)
421 fputs_filtered ("No selected stack frame.\n", stdout);
422 else
cadbb07a 423 print_stack_frame (selected_frame, selected_frame_level, 1);
777bef06 424 }
bd5635a1
RP
425}
426
427/* The inferior process has died. Long live the inferior! */
428
429void
430generic_mourn_inferior ()
431{
432 inferior_pid = 0;
433 attach_flag = 0;
434 mark_breakpoints_out ();
435 registers_changed ();
436
437#ifdef CLEAR_DEFERRED_STORES
438 /* Delete any pending stores to the inferior... */
439 CLEAR_DEFERRED_STORES;
440#endif
441
bd5635a1 442 reopen_exec_file ();
777bef06 443 if (target_has_stack) {
bd5635a1
RP
444 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
445 read_pc ()));
777bef06
JK
446 select_frame (get_current_frame (), 0);
447 } else {
bd5635a1 448 set_current_frame (0);
777bef06
JK
449 select_frame ((FRAME) 0, -1);
450 }
bd5635a1
RP
451 /* It is confusing to the user for ignore counts to stick around
452 from previous runs of the inferior. So clear them. */
453 breakpoint_clear_ignore_counts ();
454}
455
456void
457child_mourn_inferior ()
458{
459 unpush_target (&child_ops);
460 generic_mourn_inferior ();
461}
462\f
463#if 0
464/* This function is just for testing, and on some systems (Sony NewsOS
465 3.2) <sys/user.h> also includes <sys/time.h> which leads to errors
466 (since on this system at least sys/time.h is not protected against
467 multiple inclusion). */
468/* ARGSUSED */
469static void
470try_writing_regs_command (arg, from_tty)
471 char *arg;
472 int from_tty;
473{
474 register int i;
475 register int value;
476
477 if (inferior_pid == 0)
478 error ("There is no inferior process now.");
479
480 /* A Sun 3/50 or 3/60 (at least) running SunOS 4.0.3 will have a
481 kernel panic if we try to write past the end of the user area.
482 Presumably Sun will fix this bug (it has been reported), but it
483 is tacky to crash the system, so at least on SunOS4 we need to
484 stop writing when we hit the end of the user area. */
485 for (i = 0; i < sizeof (struct user); i += 2)
486 {
487 QUIT;
488 errno = 0;
489 value = call_ptrace (3, inferior_pid, i, 0);
490 call_ptrace (6, inferior_pid, i, value);
491 if (errno == 0)
492 {
493 printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
494 i, value, value);
495 }
496 else if ((i & 0377) == 0)
497 printf (" Failed at 0x%x.\n", i);
498 }
499}
500#endif
501\f
502void
503_initialize_inflow ()
504{
2a5ec41d
JG
505 int result;
506
bd5635a1
RP
507 add_info ("terminal", term_info,
508 "Print inferior's saved terminal status.");
509
510#if 0
511 add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
512 "Try writing all locations in inferior's system block.\n\
513Report which ones can be written.");
514#endif
515
516 add_com ("kill", class_run, kill_command,
517 "Kill execution of program being debugged.");
518
519 inferior_pid = 0;
520
2a5ec41d
JG
521 /* Get all the current tty settings (including whether we have a tty at
522 all!). */
523
cadbb07a 524 tflags_ours = fcntl (0, F_GETFL, 0);
2a5ec41d 525 OOPSY ("fcntl F_GETFL"); /* Should always work */
bd5635a1 526
2a5ec41d
JG
527 result = ioctl (0, TIOCGETP, &sg_ours);
528 if (result == 0) {
529 gdb_has_a_terminal = 1;
530 /* Get the rest of the tty settings, then... */
bd5635a1 531#if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
2a5ec41d 532 ioctl (0, TIOCGETC, &tc_ours);
bd5635a1 533#endif
7d9884b9 534#if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
2a5ec41d 535 ioctl (0, TIOCGLTC, &ltc_ours);
bd5635a1
RP
536#endif
537#ifdef TIOCLGET
2a5ec41d 538 ioctl (0, TIOCLGET, &lmode_ours);
bd5635a1 539#endif
bd5635a1 540#ifdef TIOCGPGRP
2a5ec41d 541 ioctl (0, TIOCGPGRP, &pgrp_ours);
bd5635a1 542#endif /* TIOCGPGRP */
2a5ec41d
JG
543 } else {
544 gdb_has_a_terminal = 0;
545 }
bd5635a1
RP
546
547 terminal_is_ours = 1;
548}
This page took 0.066166 seconds and 4 git commands to generate.