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