* core.c, eval.c, exec.c, inftarg.c, remote-adapt.c, remote-eb.c,
[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 char *strerror(); /* strings corresponding to errno */
42
43 extern struct target_ops child_ops;
44
45 /* Nonzero if we are debugging an attached outside process
46 rather than an inferior. */
47
48 int attach_flag;
49
50 \f
51 /* Record terminal status separately for debugger and inferior. */
52
53 /* Does GDB have a terminal (on stdin)? */
54 int gdb_has_a_terminal;
55
56 static TERMINAL sg_inferior;
57 static TERMINAL sg_ours;
58
59 static int tflags_inferior;
60 static int tflags_ours;
61
62 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
63 static struct tchars tc_inferior;
64 static struct tchars tc_ours;
65 #endif
66
67 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
68 static struct ltchars ltc_inferior;
69 static struct ltchars ltc_ours;
70 #endif
71
72 #ifdef TIOCLGET
73 static int lmode_inferior;
74 static int lmode_ours;
75 #endif
76
77 #ifdef TIOCGPGRP
78 # ifdef SHORT_PGRP
79 static short pgrp_inferior;
80 static short pgrp_ours;
81 # else /* not def SHORT_PGRP */
82 static int pgrp_inferior;
83 static int pgrp_ours;
84 # endif /* not def SHORT_PGRP */
85 #else /* not def TIOCGPGRP */
86 static void (*sigint_ours) ();
87 static void (*sigquit_ours) ();
88 #endif /* TIOCGPGRP */
89
90 /* The name of the tty (from the `tty' command) that we gave to the inferior
91 when it was last started. */
92
93 static char *inferior_thisrun_terminal;
94
95 /* Nonzero if our terminal settings are in effect.
96 Zero if the inferior's settings are in effect. */
97
98 static int terminal_is_ours;
99
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
107 static void terminal_ours_1 ();
108
109 /* Initialize the terminal settings we record for the inferior,
110 before we actually run the inferior. */
111
112 void
113 terminal_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
122 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
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
140 void
141 terminal_inferior ()
142 {
143 int result;
144
145 if (gdb_has_a_terminal && terminal_is_ours && inferior_thisrun_terminal == 0)
146 {
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");
152
153 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
154 result = ioctl (0, TIOCSETC, &tc_inferior);
155 OOPSY ("ioctl TIOCSETC");
156 #endif
157 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
158 result = ioctl (0, TIOCSLTC, &ltc_inferior);
159 OOPSY ("ioctl TIOCSLTC");
160 #endif
161 #ifdef TIOCLGET
162 result = ioctl (0, TIOCLSET, &lmode_inferior);
163 OOPSY ("ioctl TIOCLSET");
164 #endif
165
166 #ifdef TIOCGPGRP
167 result = ioctl (0, TIOCSPGRP, &pgrp_inferior);
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 }
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
190 void
191 terminal_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
200 void
201 terminal_ours ()
202 {
203 terminal_ours_1 (0);
204 }
205
206 static void
207 terminal_ours_1 (output_only)
208 int output_only;
209 {
210 int result;
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
216 /* Checking inferior_thisrun_terminal is necessary so that
217 if GDB is running in the background, it won't block trying
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)
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
230 result = ioctl (0, TIOCGPGRP, &pgrp_inferior);
231 result = ioctl (0, TIOCSPGRP, &pgrp_ours);
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);
240 result = ioctl (0, TIOCGETP, &sg_inferior);
241
242 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
243 result = ioctl (0, TIOCGETC, &tc_inferior);
244 #endif
245 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
246 result = ioctl (0, TIOCGLTC, &ltc_inferior);
247 #endif
248 #ifdef TIOCLGET
249 result = ioctl (0, TIOCLGET, &lmode_inferior);
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
263 result = fcntl (0, F_SETFL, tflags_ours);
264 result = fcntl (0, F_SETFL, tflags_ours);
265 result = ioctl (0, TIOCSETN, &sg_ours);
266
267 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
268 result = ioctl (0, TIOCSETC, &tc_ours);
269 #endif
270 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
271 result = ioctl (0, TIOCSLTC, &ltc_ours);
272 #endif
273 #ifdef TIOCLGET
274 result = ioctl (0, TIOCLSET, &lmode_ours);
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 */
285 void
286 term_info (arg, from_tty)
287 char *arg;
288 int from_tty;
289 {
290 target_terminal_info (arg, from_tty);
291 }
292
293 /* ARGSUSED */
294 void
295 child_terminal_info (args, from_tty)
296 char *args;
297 int from_tty;
298 {
299 register int i;
300
301 if (!gdb_has_a_terminal) {
302 printf_filtered ("This GDB does not control a terminal.\n");
303 return;
304 }
305
306 #ifdef TIOCGPGRP
307 printf_filtered ("Inferior's terminal status (currently saved by GDB):\n");
308
309 printf_filtered ("owner pgrp = %d, fcntl flags = 0x%x.\n",
310 pgrp_inferior, tflags_inferior);
311 #endif /* TIOCGPGRP */
312
313 #ifdef HAVE_TERMIO
314
315 printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
316 sg_inferior.c_iflag, sg_inferior.c_oflag);
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
326 printf_filtered ("sgttyb.sg_flags = 0x%x.\n", sg_inferior.sg_flags);
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++)
333 printf_filtered ("0x%x ", ((unsigned char *)&tc_inferior)[i]);
334 printf_filtered ("\n");
335 #endif
336
337 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
338 printf_filtered ("ltchars: ");
339 for (i = 0; i < (int)sizeof (struct ltchars); i++)
340 printf_filtered ("0x%x ", ((unsigned char *)&ltc_inferior)[i]);
341 printf_filtered ("\n");
342 #endif
343
344 #ifdef TIOCLGET
345 printf_filtered ("lmode: 0x%x\n", lmode_inferior);
346 #endif
347 }
348 \f
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.
353
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
358 void
359 new_tty_prefork (ttyname)
360 char *ttyname;
361 {
362 /* Save the name for later, for determining whether we and the child
363 are sharing a tty. */
364 inferior_thisrun_terminal = ttyname;
365 }
366
367 void
368 new_tty ()
369 {
370 register int tty;
371
372 if (inferior_thisrun_terminal == 0)
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
387 #ifdef USE_O_NOCTTY
388 tty = open(inferior_thisrun_terminal, O_RDWR | O_NOCTTY);
389 #else
390 tty = open(inferior_thisrun_terminal, O_RDWR);
391 #endif
392 if (tty == -1)
393 {
394 print_sys_errmsg (inferior_thisrun_terminal, errno);
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 */
412 static void
413 kill_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);
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
430 print_stack_frame (selected_frame, selected_frame_level, 1);
431 }
432 }
433
434 /* The inferior process has died. Long live the inferior! */
435
436 void
437 generic_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
449 reopen_exec_file ();
450 if (target_has_stack) {
451 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
452 read_pc ()));
453 select_frame (get_current_frame (), 0);
454 } else {
455 set_current_frame (0);
456 select_frame ((FRAME) 0, -1);
457 }
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
463 void
464 child_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 */
476 static void
477 try_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
509 void
510 _initialize_inflow ()
511 {
512 int result;
513
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\
520 Report 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
528 /* Get all the current tty settings (including whether we have a tty at
529 all!). */
530
531 tflags_ours = fcntl (0, F_GETFL, 0);
532 OOPSY ("fcntl F_GETFL"); /* Should always work */
533
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... */
538 #if defined(TIOCGETC) && !defined(TIOCGETC_BROKEN)
539 ioctl (0, TIOCGETC, &tc_ours);
540 #endif
541 #if defined(TIOCGLTC) && !defined(TIOCGLTC_BROKEN)
542 ioctl (0, TIOCGLTC, &ltc_ours);
543 #endif
544 #ifdef TIOCLGET
545 ioctl (0, TIOCLGET, &lmode_ours);
546 #endif
547 #ifdef TIOCGPGRP
548 ioctl (0, TIOCGPGRP, &pgrp_ours);
549 #endif /* TIOCGPGRP */
550 } else {
551 gdb_has_a_terminal = 0;
552 }
553
554 terminal_is_ours = 1;
555 }
This page took 0.040465 seconds and 5 git commands to generate.