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