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