gdb-3.1
[external/binutils.git] / gdb / inflow.c
1 /* Low level interface to ptrace, for GDB when running under Unix.
2    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
3
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY.  No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
9
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License.  A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities.  It
14 should be in a file named COPYING.  Among other things, the copyright
15 notice and this notice must be preserved on all copies.
16
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther.  Help stamp out software hoarding!
19 */
20 #include "defs.h"
21 #include "param.h"
22 #include "frame.h"
23 #include "inferior.h"
24
25 #ifdef USG
26 #include <sys/types.h>
27 #include <fcntl.h>
28 #endif
29
30 #include <stdio.h>
31 #include <sys/param.h>
32 #include <sys/dir.h>
33 #include <signal.h>
34
35 #ifdef HAVE_TERMIO
36 #include <termio.h>
37 #undef TIOCGETP
38 #define TIOCGETP TCGETA
39 #undef TIOCSETN
40 #define TIOCSETN TCSETA
41 #undef TIOCSETP
42 #define TIOCSETP TCSETAF
43 #define TERMINAL struct termio
44 #else
45 #include <sys/ioctl.h>
46 #include <fcntl.h>
47 #include <sgtty.h>
48 #define TERMINAL struct sgttyb
49 #endif
50
51 #ifdef SET_STACK_LIMIT_HUGE
52 #include <sys/time.h>
53 #include <sys/resource.h>
54 extern int original_stack_limit;
55 #endif /* SET_STACK_LIMIT_HUGE */
56
57 extern int errno;
58
59 /* Nonzero if we are debugging an attached outside process
60    rather than an inferior.  */
61
62 int attach_flag;
63
64 \f
65 /* Record terminal status separately for debugger and inferior.  */
66
67 static TERMINAL sg_inferior;
68 static TERMINAL sg_ours;
69
70 static int tflags_inferior;
71 static int tflags_ours;
72
73 #ifdef TIOCGETC
74 static struct tchars tc_inferior;
75 static struct tchars tc_ours;
76 #endif
77
78 #ifdef TIOCGLTC
79 static struct ltchars ltc_inferior;
80 static struct ltchars ltc_ours;
81 #endif /* TIOCGLTC */
82
83 #ifdef TIOCLGET
84 static int lmode_inferior;
85 static int lmode_ours;
86 #endif
87
88 #ifdef TIOCGPGRP
89 static int pgrp_inferior;
90 static int pgrp_ours;
91 #else
92 static int (*sigint_ours) ();
93 static int (*sigquit_ours) ();
94 #endif /* TIOCGPGRP */
95
96 /* Copy of inferior_io_terminal when inferior was last started.  */
97 static char *inferior_thisrun_terminal;
98
99 static void terminal_ours_1 ();
100
101 /* Nonzero if our terminal settings are in effect.
102    Zero if the inferior's settings are in effect.  */
103 static int terminal_is_ours;
104
105 /* Initialize the terminal settings we record for the inferior,
106    before we actually run the inferior.  */
107
108 void
109 terminal_init_inferior ()
110 {
111   if (remote_debugging)
112     return;
113
114   sg_inferior = sg_ours;
115   tflags_inferior = tflags_ours;
116
117 #ifdef TIOCGETC
118   tc_inferior = tc_ours;
119 #endif
120
121 #ifdef TIOCGLTC
122   ltc_inferior = ltc_ours;
123 #endif
124
125 #ifdef TIOCLGET
126   lmode_inferior = lmode_ours;
127 #endif
128
129 #ifdef TIOCGPGRP
130   pgrp_inferior = inferior_pid;
131 #endif /* TIOCGPGRP */
132
133   terminal_is_ours = 1;
134 }
135
136 /* Put the inferior's terminal settings into effect.
137    This is preparation for starting or resuming the inferior.  */
138
139 void
140 terminal_inferior ()
141 {
142   if (remote_debugging)
143     return;
144
145   if (terminal_is_ours)   /*  && inferior_thisrun_terminal == 0) */
146     {
147       fcntl (0, F_SETFL, tflags_inferior);
148       fcntl (0, F_SETFL, tflags_inferior);
149       ioctl (0, TIOCSETN, &sg_inferior);
150 #ifdef TIOCGETC
151       ioctl (0, TIOCSETC, &tc_inferior);
152 #endif
153 #ifdef TIOCGLTC
154       ioctl (0, TIOCSLTC, &ltc_inferior);
155 #endif
156 #ifdef TIOCLGET
157       ioctl (0, TIOCLSET, &lmode_inferior);
158 #endif
159
160 #ifdef TIOCGPGRP
161       ioctl (0, TIOCSPGRP, &pgrp_inferior);
162 #else
163       sigint_ours = (int (*) ()) signal (SIGINT, SIG_IGN);
164       sigquit_ours = (int (*) ()) signal (SIGQUIT, SIG_IGN);
165 #endif /* TIOCGPGRP */
166     }
167   terminal_is_ours = 0;
168 }
169
170 /* Put some of our terminal settings into effect,
171    enough to get proper results from our output,
172    but do not change into or out of RAW mode
173    so that no input is discarded.
174
175    After doing this, either terminal_ours or terminal_inferior
176    should be called to get back to a normal state of affairs.  */
177
178 void
179 terminal_ours_for_output ()
180 {
181   if (remote_debugging)
182     return;
183
184   terminal_ours_1 (1);
185 }
186
187 /* Put our terminal settings into effect.
188    First record the inferior's terminal settings
189    so they can be restored properly later.  */
190
191 void
192 terminal_ours ()
193 {
194   if (remote_debugging)
195     return;
196
197   terminal_ours_1 (0);
198 }
199
200 static void
201 terminal_ours_1 (output_only)
202      int output_only;
203 {
204 #ifdef TIOCGPGRP
205   /* Ignore this signal since it will happen when we try to set the pgrp.  */
206   int (*osigttou) ();
207 #endif /* TIOCGPGRP */
208
209   if (!terminal_is_ours)  /*   && inferior_thisrun_terminal == 0)  */
210     {
211       terminal_is_ours = 1;
212
213 #ifdef TIOCGPGRP
214       osigttou = signal (SIGTTOU, SIG_IGN);
215
216       ioctl (0, TIOCGPGRP, &pgrp_inferior);
217       ioctl (0, TIOCSPGRP, &pgrp_ours);
218
219       signal (SIGTTOU, osigttou);
220 #else
221       signal (SIGINT, sigint_ours);
222       signal (SIGQUIT, sigquit_ours);
223 #endif /* TIOCGPGRP */
224
225       tflags_inferior = fcntl (0, F_GETFL, 0);
226       ioctl (0, TIOCGETP, &sg_inferior);
227
228 #ifdef TIOCGETC
229       ioctl (0, TIOCGETC, &tc_inferior);
230 #endif
231 #ifdef TIOCGLTC
232       ioctl (0, TIOCGLTC, &ltc_inferior);
233 #endif
234 #ifdef TIOCLGET
235       ioctl (0, TIOCLGET, &lmode_inferior);
236 #endif
237     }
238
239 #ifdef HAVE_TERMIO
240   sg_ours.c_lflag |= ICANON;
241   if (output_only && !(sg_inferior.c_lflag & ICANON))
242     sg_ours.c_lflag &= ~ICANON;
243 #else /* not HAVE_TERMIO */
244   sg_ours.sg_flags &= ~RAW & ~CBREAK;
245   if (output_only)
246     sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
247 #endif /* not HAVE_TERMIO */
248
249   fcntl (0, F_SETFL, tflags_ours);
250   fcntl (0, F_SETFL, tflags_ours);
251   ioctl (0, TIOCSETN, &sg_ours);
252
253 #ifdef TIOCGETC
254   ioctl (0, TIOCSETC, &tc_ours);
255 #endif
256 #ifdef TIOCGLTC
257   ioctl (0, TIOCSLTC, &ltc_ours);
258 #endif
259 #ifdef TIOCLGET
260   ioctl (0, TIOCLSET, &lmode_ours);
261 #endif
262
263
264 #ifdef HAVE_TERMIO
265   sg_ours.c_lflag |= ICANON;
266 #else /* not HAVE_TERMIO */
267   sg_ours.sg_flags &= ~RAW & ~CBREAK;
268 #endif /* not HAVE_TERMIO */
269 }
270
271 static void
272 term_status_command ()
273 {
274   register int i;
275
276   if (remote_debugging)
277     {
278       printf ("No terminal status when remote debugging.\n");
279       return;
280     }
281
282   printf ("Inferior's terminal status (currently saved by GDB):\n");
283
284 #ifdef HAVE_TERMIO
285
286   printf ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
287           tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
288   printf ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
289           sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
290   printf ("c_cc: ");
291   for (i = 0; (i < NCC); i += 1)
292     printf ("0x%x ", sg_inferior.c_cc[i]);
293   printf ("\n");
294
295 #else /* not HAVE_TERMIO */
296
297   printf ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n",
298           tflags_inferior, sg_inferior.sg_flags, pgrp_inferior);
299
300 #endif /* not HAVE_TERMIO */
301
302 #ifdef TIOCGETC
303   printf ("tchars: ");
304   for (i = 0; i < sizeof (struct tchars); i++)
305     printf ("0x%x ", ((char *)&tc_inferior)[i]);
306   printf ("\n");
307 #endif
308
309 #ifdef TIOCGLTC
310   printf ("ltchars: ");
311   for (i = 0; i < sizeof (struct ltchars); i++)
312     printf ("0x%x ", ((char *)&ltc_inferior)[i]);
313   printf ("\n");
314   ioctl (0, TIOCSLTC, &ltc_ours);
315 #endif
316
317 #ifdef TIOCLGET
318   printf ("lmode:  %x\n", lmode_inferior);
319 #endif
320 }
321 \f
322 static void
323 new_tty (ttyname)
324      char *ttyname;
325 {
326   register int tty;
327   register int fd;
328
329 #ifdef TIOCNOTTY
330   /* Disconnect the child process from our controlling terminal.  */
331   tty = open("/dev/tty", O_RDWR);
332   if (tty > 0)
333     {
334       ioctl(tty, TIOCNOTTY, 0);
335       close(tty);
336     }
337 #endif
338
339   /* Now open the specified new terminal.  */
340
341   tty = open(ttyname, O_RDWR);
342   if (tty == -1)
343     _exit(1);
344
345   dup2(tty, 0);
346   dup2(tty, 1);
347   dup2(tty, 2);
348   close(tty);
349 }
350 \f
351 /* Start an inferior process and returns its pid.
352    ALLARGS is a string containing shell command to run the program.
353    ENV is the environment vector to pass.  */
354
355 #ifndef SHELL_FILE
356 #define SHELL_FILE "/bin/sh"
357 #endif
358
359 int
360 create_inferior (allargs, env)
361      char *allargs;
362      char **env;
363 {
364   int pid;
365   char *shell_command;
366   extern int sys_nerr;
367   extern char *sys_errlist[];
368   extern int errno;
369
370   /* If desired, concat something onto the front of ALLARGS.
371      SHELL_COMMAND is the result.  */
372 #ifdef SHELL_COMMAND_CONCAT
373   shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + strlen (allargs) + 1);
374   strcpy (shell_command, SHELL_COMMAND_CONCAT);
375   strcat (shell_command, allargs);
376 #else
377   shell_command = allargs;
378 #endif
379
380   /* exec is said to fail if the executable is open.  */
381   close_exec_file ();
382
383   pid = fork ();
384   if (pid < 0)
385     perror_with_name ("fork");
386
387   if (pid == 0)
388     {
389 #ifdef TIOCGPGRP
390       /* Run inferior in a separate process group.  */
391       setpgrp (getpid (), getpid ());
392 #endif /* TIOCGPGRP */
393
394 #ifdef SET_STACK_LIMIT_HUGE
395       /* Reset the stack limit back to what it was.  */
396       {
397         struct rlimit rlim;
398
399         getrlimit (RLIMIT_STACK, &rlim);
400         rlim.rlim_cur = original_stack_limit;
401         setrlimit (RLIMIT_STACK, &rlim);
402       }
403 #endif /* SET_STACK_LIMIT_HUGE */
404
405
406       inferior_thisrun_terminal = inferior_io_terminal;
407       if (inferior_io_terminal != 0)
408         new_tty (inferior_io_terminal);
409
410 /* Not needed on Sun, at least, and loses there
411    because it clobbers the superior.  */
412 /*???      signal (SIGQUIT, SIG_DFL);
413       signal (SIGINT, SIG_DFL);  */
414
415       call_ptrace (0);
416       execle (SHELL_FILE, "sh", "-c", shell_command, 0, env);
417
418       fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
419                errno < sys_nerr ? sys_errlist[errno] : "unknown error");
420       fflush (stderr);
421       _exit (0177);
422     }
423   return pid;
424 }
425
426 /* Kill the inferior process.  Make us have no inferior.  */
427
428 static void
429 kill_command ()
430 {
431   if (remote_debugging)
432     return;
433   if (inferior_pid == 0)
434     error ("The program is not being run.");
435   if (!query ("Kill the inferior process? "))
436     error ("Not confirmed.");
437   kill_inferior ();
438 }
439
440 void
441 inferior_died ()
442 {
443   inferior_pid = 0;
444   attach_flag = 0;
445   mark_breakpoints_out ();
446   select_frame ( (FRAME) 0, -1);
447   reopen_exec_file ();
448   if (have_core_file_p ())
449     set_current_frame ( create_new_frame (read_register (FP_REGNUM),
450                                           read_pc ()));
451 }
452 \f
453 static void
454 try_writing_regs_command ()
455 {
456   register int i;
457   register int value;
458   extern int errno;
459
460   if (inferior_pid == 0)
461     error ("There is no inferior process now.");
462
463   for (i = 0; ; i += 2)
464     {
465       QUIT;
466       errno = 0;
467       value = call_ptrace (3, inferior_pid, i, 0);
468       call_ptrace (6, inferior_pid, i, value);
469       if (errno == 0)
470         {
471           printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
472                   i, value, value);
473         }
474       else if ((i & 0377) == 0)
475         printf (" Failed at 0x%x.\n", i);
476     }
477 }
478 \f
479 void
480 _initialize_inflow ()
481 {
482   add_com ("term-status", class_obscure, term_status_command,
483            "Print info on inferior's saved terminal status.");
484
485   add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
486            "Try writing all locations in inferior's system block.\n\
487 Report which ones can be written.");
488
489   add_com ("kill", class_run, kill_command,
490            "Kill execution of program being debugged.");
491
492   inferior_pid = 0;
493
494   ioctl (0, TIOCGETP, &sg_ours);
495   fcntl (0, F_GETFL, tflags_ours);
496
497 #ifdef TIOCGETC
498   ioctl (0, TIOCGETC, &tc_ours);
499 #endif
500 #ifdef TIOCGLTC
501   ioctl (0, TIOCGLTC, &ltc_ours);
502 #endif
503 #ifdef TIOCLGET
504   ioctl (0, TIOCLGET, &lmode_ours);
505 #endif
506
507 #ifdef TIOCGPGRP
508   ioctl (0, TIOCGPGRP, &pgrp_ours);
509 #endif /* TIOCGPGRP */
510
511   terminal_is_ours = 1;
512 }
513