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