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