* defs.h: Incorporate param.h. All users changed.
[deliverable/binutils-gdb.git] / gdb / inflow.c
1 /* Low level interface to ptrace, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include <stdio.h>
21 #include "defs.h"
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
41 extern struct target_ops child_ops;
42
43 /* Nonzero if we are debugging an attached outside process
44 rather than an inferior. */
45
46 int attach_flag;
47
48 \f
49 /* Record terminal status separately for debugger and inferior. */
50
51 static TERMINAL sg_inferior;
52 static TERMINAL sg_ours;
53
54 static int tflags_inferior;
55 static int tflags_ours;
56
57 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
58 static struct tchars tc_inferior;
59 static struct tchars tc_ours;
60 #endif
61
62 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
63 static struct ltchars ltc_inferior;
64 static struct ltchars ltc_ours;
65 #endif
66
67 #ifdef TIOCLGET
68 static int lmode_inferior;
69 static int lmode_ours;
70 #endif
71
72 #ifdef TIOCGPGRP
73 # ifdef SHORT_PGRP
74 static short pgrp_inferior;
75 static short pgrp_ours;
76 # else
77 static int pgrp_inferior;
78 static int pgrp_ours;
79 # endif
80 #else
81 static void (*sigint_ours) ();
82 static void (*sigquit_ours) ();
83 #endif /* TIOCGPGRP */
84
85 /* Copy of inferior_io_terminal when inferior was last started. */
86 static char *inferior_thisrun_terminal;
87
88 static void terminal_ours_1 ();
89
90 /* Nonzero if our terminal settings are in effect.
91 Zero if the inferior's settings are in effect. */
92 static int terminal_is_ours;
93
94 /* Initialize the terminal settings we record for the inferior,
95 before we actually run the inferior. */
96
97 void
98 terminal_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
107 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
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
125 void
126 terminal_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
137 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
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
162 void
163 terminal_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
172 void
173 terminal_ours ()
174 {
175 terminal_ours_1 (0);
176 }
177
178 static void
179 terminal_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
217 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
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
242 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
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 */
257 void
258 term_info (arg, from_tty)
259 char *arg;
260 int from_tty;
261 {
262 target_terminal_info (arg, from_tty);
263 }
264
265 /* ARGSUSED */
266 void
267 child_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
300 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
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
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.
316
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
321 void
322 new_tty_prefork (ttyname)
323 char *ttyname;
324 {
325 /* Save the name for later, for determining whether we and the child
326 are sharing a tty. */
327 inferior_thisrun_terminal = ttyname;
328 }
329
330 void
331 new_tty ()
332 {
333 register int tty;
334
335 if (inferior_thisrun_terminal == 0)
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
350 #ifdef USE_O_NOCTTY
351 tty = open(inferior_thisrun_terminal, O_RDWR | O_NOCTTY);
352 #else
353 tty = open(inferior_thisrun_terminal, O_RDWR);
354 #endif
355 if (tty == -1)
356 {
357 print_sys_errmsg (inferior_thisrun_terminal, errno);
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 */
375 static void
376 kill_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);
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
393 print_stack_frame (selected_frame, selected_frame_level, 1);
394 }
395 }
396
397 /* The inferior process has died. Long live the inferior! */
398
399 void
400 generic_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
412 reopen_exec_file ();
413 if (target_has_stack) {
414 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
415 read_pc ()));
416 select_frame (get_current_frame (), 0);
417 } else {
418 set_current_frame (0);
419 select_frame ((FRAME) 0, -1);
420 }
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
426 void
427 child_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 */
439 static void
440 try_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
472 void
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\
481 Report 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);
490 tflags_ours = fcntl (0, F_GETFL, 0);
491
492 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
493 ioctl (0, TIOCGETC, &tc_ours);
494 #endif
495 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
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.047409 seconds and 5 git commands to generate.