]> Git Repo - binutils.git/blob - gdb/inflow.c
* coffread.c (read_enum_type): Use the size of a target int when
[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 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.056717 seconds and 4 git commands to generate.