]> Git Repo - binutils.git/blob - gdb/inflow.c
More filename renaming.
[binutils.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.050662 seconds and 4 git commands to generate.