Initial import from FreeBSD RELENG_4:
[games.git] / contrib / gdb / gdb / inftarg.c
1 /* Target-vector operations for controlling Unix child processes, for GDB.
2    Copyright 1990-1996, 1998, 1999 Free Software Foundation, Inc.
3    Contributed by Cygnus Support.
4
5 ## Contains temporary hacks..
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23 #include "defs.h"
24 #include "frame.h"  /* required by inferior.h */
25 #include "inferior.h"
26 #include "target.h"
27 #include "gdbcore.h"
28 #include "command.h"
29 #include "gdb_stat.h"
30 #include <signal.h>
31 #include <sys/types.h>
32 #include <fcntl.h>
33
34 #ifdef HAVE_WAIT_H
35 # include <wait.h>
36 #else
37 # ifdef HAVE_SYS_WAIT_H
38 #  include <sys/wait.h>
39 # endif
40 #endif
41
42 /* "wait.h" fills in the gaps left by <wait.h> */
43 #include "wait.h"
44 #ifdef HAVE_UNISTD_H
45 #include <unistd.h>
46 #endif
47
48 extern struct symtab_and_line *
49 child_enable_exception_callback PARAMS ((enum exception_event_kind, int));
50
51 extern struct exception_event_record *
52 child_get_current_exception_event PARAMS ((void));
53
54 extern void _initialize_inftarg PARAMS ((void));
55
56 static void
57 child_prepare_to_store PARAMS ((void));
58
59 #ifndef CHILD_WAIT
60 static int child_wait PARAMS ((int, struct target_waitstatus *));
61 #endif /* CHILD_WAIT */
62
63 #if !defined(CHILD_POST_WAIT)
64 void
65 child_post_wait PARAMS ((int, int));
66 #endif
67
68 static void child_open PARAMS ((char *, int));
69
70 static void
71 child_files_info PARAMS ((struct target_ops *));
72
73 static void
74 child_detach PARAMS ((char *, int));
75
76 static void
77 child_detach_from_process PARAMS ((int, char *, int, int));
78
79 static void
80 child_attach PARAMS ((char *, int));
81
82 static void
83 child_attach_to_process PARAMS ((char *, int, int));
84
85 #if !defined(CHILD_POST_ATTACH)
86 extern void child_post_attach PARAMS ((int));
87 #endif
88
89 static void
90 child_require_attach PARAMS ((char *, int));
91
92 static void
93 child_require_detach PARAMS ((int, char *, int));
94
95 static void
96 ptrace_me PARAMS ((void));
97
98 static void 
99 ptrace_him PARAMS ((int));
100
101 static void 
102 child_create_inferior PARAMS ((char *, char *, char **));
103
104 static void
105 child_mourn_inferior PARAMS ((void));
106
107 static int
108 child_can_run PARAMS ((void));
109
110 static void
111 child_stop PARAMS ((void));
112
113 #ifndef CHILD_THREAD_ALIVE
114 int child_thread_alive PARAMS ((int));
115 #endif
116
117 static void init_child_ops PARAMS ((void));
118
119 extern char **environ;
120
121 struct target_ops child_ops;
122
123 int child_suppress_run = 0;     /* Non-zero if inftarg should pretend not to
124                                    be a runnable target.  Used by targets
125                                    that can sit atop inftarg, such as HPUX
126                                    thread support.  */
127
128 #ifndef CHILD_WAIT
129
130 /*##*/
131 /* Enable HACK for ttrace work.  In
132  * infttrace.c/require_notification_of_events,
133  * this is set to 0 so that the loop in child_wait
134  * won't loop.
135  */
136 int not_same_real_pid = 1;
137 /*##*/
138
139
140 /* Wait for child to do something.  Return pid of child, or -1 in case
141    of error; store status through argument pointer OURSTATUS.  */
142
143 static int
144 child_wait (pid, ourstatus)
145      int pid;
146      struct target_waitstatus *ourstatus;
147 {
148   int save_errno;
149   int status;
150   char *  execd_pathname;
151   int  exit_status;
152   int  related_pid;
153   int  syscall_id;
154   enum target_waitkind  kind;
155
156   do {
157     set_sigint_trap();  /* Causes SIGINT to be passed on to the
158                            attached process. */
159     set_sigio_trap ();
160
161     pid = ptrace_wait (inferior_pid, &status);
162
163     save_errno = errno;
164
165     clear_sigio_trap ();
166
167     clear_sigint_trap();
168
169     if (pid == -1)
170       {
171         if (save_errno == EINTR)
172           continue;
173
174         fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
175                  safe_strerror (save_errno));
176
177         /* Claim it exited with unknown signal.  */
178         ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
179         ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
180         return -1;
181       }
182
183     /* Did it exit?
184      */
185     if (target_has_exited (pid, status, &exit_status))
186       {
187         /* ??rehrauer: For now, ignore this. */
188         continue;
189       }
190
191     if (!target_thread_alive (pid))
192       {
193         ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
194         return pid;
195       }
196       
197     if (target_has_forked (pid, &related_pid)
198          && ((pid == inferior_pid) || (related_pid == inferior_pid)))
199       {
200         ourstatus->kind = TARGET_WAITKIND_FORKED;
201         ourstatus->value.related_pid = related_pid;
202         return pid;
203       }
204
205     if (target_has_vforked (pid, &related_pid)
206          && ((pid == inferior_pid) || (related_pid == inferior_pid)))
207       {
208         ourstatus->kind = TARGET_WAITKIND_VFORKED;
209         ourstatus->value.related_pid = related_pid;
210         return pid;
211       }
212
213     if (target_has_execd (pid, &execd_pathname))
214       {
215         /* Are we ignoring initial exec events?  (This is likely because
216            we're in the process of starting up the inferior, and another
217            (older) mechanism handles those.)  If so, we'll report this
218            as a regular stop, not an exec.
219            */
220         if (inferior_ignoring_startup_exec_events)
221           {
222             inferior_ignoring_startup_exec_events--;
223           }
224         else
225           {
226             ourstatus->kind = TARGET_WAITKIND_EXECD;
227             ourstatus->value.execd_pathname = execd_pathname;
228             return pid;
229           }
230       }
231
232     /* All we must do with these is communicate their occurrence
233        to wait_for_inferior...
234        */
235     if (target_has_syscall_event (pid, &kind, &syscall_id))
236       {
237         ourstatus->kind = kind;
238         ourstatus->value.syscall_id = syscall_id;
239         return pid;
240       }
241
242 /*##  } while (pid != inferior_pid); ##*/ /* Some other child died or stopped */
243 /* hack for thread testing */
244       } while( (pid != inferior_pid) && not_same_real_pid );
245 /*##*/
246
247   store_waitstatus (ourstatus, status);
248   return pid;
249 }
250 #endif /* CHILD_WAIT */
251
252 #if !defined(CHILD_POST_WAIT)
253 void
254 child_post_wait (pid, wait_status)
255   int  pid;
256   int  wait_status;
257 {
258   /* This version of Unix doesn't require a meaningful "post wait"
259      operation.
260      */
261 }
262 #endif
263  
264
265 #ifndef CHILD_THREAD_ALIVE
266
267 /* Check to see if the given thread is alive.
268
269    FIXME: Is kill() ever the right way to do this?  I doubt it, but
270    for now we're going to try and be compatable with the old thread
271    code.  */
272 int
273 child_thread_alive (pid)
274      int pid;
275 {
276   return (kill (pid, 0) != -1);
277 }
278
279 #endif
280
281 static void
282 child_attach_to_process (args, from_tty, after_fork)
283   char *  args;
284   int  from_tty;
285   int  after_fork;
286 {
287   if (!args)
288     error_no_arg ("process-id to attach");
289
290 #ifndef ATTACH_DETACH
291   error ("Can't attach to a process on this machine.");
292 #else
293   {
294     char *exec_file;
295     int pid;
296     char *dummy;
297
298     dummy = args;
299     pid = strtol (args, &dummy, 0);
300     /* Some targets don't set errno on errors, grrr! */
301     if ((pid == 0) && (args == dummy))
302       error ("Illegal process-id: %s\n", args);
303
304     if (pid == getpid())                /* Trying to masturbate? */
305       error ("I refuse to debug myself!");
306
307     if (from_tty)
308       {
309         exec_file = (char *) get_exec_file (0);
310
311         if (after_fork)
312           printf_unfiltered ("Attaching after fork to %s\n", 
313                   target_pid_to_str (pid));
314         else if (exec_file)
315           printf_unfiltered ("Attaching to program: %s, %s\n", exec_file,
316                   target_pid_to_str (pid));
317         else
318           printf_unfiltered ("Attaching to %s\n", target_pid_to_str (pid));
319
320         gdb_flush (gdb_stdout);
321       }
322
323     if (!after_fork)
324       attach (pid);
325     else
326       REQUIRE_ATTACH (pid);
327
328     inferior_pid = pid;
329     push_target (&child_ops);
330   }
331 #endif  /* ATTACH_DETACH */
332 }
333
334
335 /* Attach to process PID, then initialize for debugging it.  */
336
337 static void
338 child_attach (args, from_tty)
339      char *args;
340      int from_tty;
341 {
342   child_attach_to_process (args, from_tty, 0);
343 }
344
345 #if !defined(CHILD_POST_ATTACH)
346 void
347 child_post_attach (pid)
348   int  pid;
349 {
350   /* This version of Unix doesn't require a meaningful "post attach"
351      operation by a debugger.  */
352 }
353 #endif
354
355 static void
356 child_require_attach (args, from_tty)
357      char *args;
358      int from_tty;
359 {
360   child_attach_to_process (args, from_tty, 1);
361
362
363 static void
364 child_detach_from_process (pid, args, from_tty, after_fork)
365   int  pid;
366   char *  args;
367   int  from_tty;
368   int  after_fork;
369 {
370 #ifdef ATTACH_DETACH
371   {
372     int siggnal = 0;
373
374     if (from_tty)
375       {
376         char *exec_file = get_exec_file (0);
377         if (exec_file == 0)
378           exec_file = "";
379         if (after_fork)
380           printf_unfiltered ("Detaching after fork from %s\n",
381                              target_pid_to_str (pid));
382         else
383           printf_unfiltered ("Detaching from program: %s, %s\n", exec_file,
384                              target_pid_to_str (pid));
385         gdb_flush (gdb_stdout);
386       }
387     if (args)
388       siggnal = atoi (args);
389
390     if (!after_fork)
391       detach (siggnal);
392     else
393       REQUIRE_DETACH (pid, siggnal);
394   }
395 #else
396   error ("This version of Unix does not support detaching a process.");
397 #endif
398 }
399
400 /* Take a program previously attached to and detaches it.
401    The program resumes execution and will no longer stop
402    on signals, etc.  We'd better not have left any breakpoints
403    in the program or it'll die when it hits one.  For this
404    to work, it may be necessary for the process to have been
405    previously attached.  It *might* work if the program was
406    started via the normal ptrace (PTRACE_TRACEME).  */
407
408 static void
409 child_detach (args, from_tty)
410      char *args;
411      int from_tty;
412 {
413   child_detach_from_process (inferior_pid, args, from_tty, 0);
414   inferior_pid = 0;
415   unpush_target (&child_ops);
416 }
417
418 static void
419 child_require_detach (pid, args, from_tty)
420   int  pid;
421   char *  args;
422   int  from_tty;
423 {
424   child_detach_from_process (pid, args, from_tty, 1);
425 }
426
427
428 /* Get ready to modify the registers array.  On machines which store
429    individual registers, this doesn't need to do anything.  On machines
430    which store all the registers in one fell swoop, this makes sure
431    that registers contains all the registers from the program being
432    debugged.  */
433
434 static void
435 child_prepare_to_store ()
436 {
437 #ifdef CHILD_PREPARE_TO_STORE
438   CHILD_PREPARE_TO_STORE ();
439 #endif
440 }
441
442 /* Print status information about what we're accessing.  */
443
444 static void
445 child_files_info (ignore)
446      struct target_ops *ignore;
447 {
448   printf_unfiltered ("\tUsing the running image of %s %s.\n",
449           attach_flag? "attached": "child", target_pid_to_str (inferior_pid));
450 }
451
452 /* ARGSUSED */
453 static void
454 child_open (arg, from_tty)
455      char *arg;
456      int from_tty;
457 {
458   error ("Use the \"run\" command to start a Unix child process.");
459 }
460
461 /* Stub function which causes the inferior that runs it, to be ptrace-able
462    by its parent process.  */
463
464 static void
465 ptrace_me ()
466 {
467   /* "Trace me, Dr. Memory!" */
468   call_ptrace (0, 0, (PTRACE_ARG3_TYPE) 0, 0);
469 }
470
471 /* Stub function which causes the GDB that runs it, to start ptrace-ing
472    the child process.  */
473
474 static void 
475 ptrace_him (pid)
476      int pid;
477 {
478   push_target (&child_ops);
479
480   /* On some targets, there must be some explicit synchronization
481      between the parent and child processes after the debugger
482      forks, and before the child execs the debuggee program.  This
483      call basically gives permission for the child to exec.
484      */
485
486   target_acknowledge_created_inferior (pid);
487
488   /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h,
489    * and will be 1 or 2 depending on whether we're starting
490    * without or with a shell.
491    */
492   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
493
494   /* On some targets, there must be some explicit actions taken after
495      the inferior has been started up.
496      */
497   target_post_startup_inferior (pid);
498 }
499
500 /* Start an inferior Unix child process and sets inferior_pid to its pid.
501    EXEC_FILE is the file to run.
502    ALLARGS is a string containing the arguments to the program.
503    ENV is the environment vector to pass.  Errors reported with error().  */
504
505 static void
506 child_create_inferior (exec_file, allargs, env)
507      char *exec_file;
508      char *allargs;
509      char **env;
510 {
511
512 #ifdef HPUXHPPA
513   char *tryname;
514   char *shell_file;
515   char *p;
516   char *p1;
517   char *path = getenv ("PATH");
518   int len;
519   struct stat statbuf;
520
521   /* On HP-UX, we have a possible bad interaction between
522    * the start-up-with-shell code and our catch-fork/catch-exec
523    * logic. To avoid the bad interaction, we start up with the
524    * C shell ("csh") and pass it the "-f" flag (fast start-up,
525    * don't run .cshrc code).
526    * See further comments in inferior.h toward the bottom
527    * (STARTUP_WITH_SHELL flag) and in fork-child.c
528    */
529
530   /* Rather than passing in a hard-wired path like "/bin/csh",
531    * we look down the PATH to find csh. I took this code from
532    * procfs.c, which is the file in the Sun-specific part of GDB
533    * analogous to inftarg.c. See procfs.c for more detailed 
534    * comments. - RT
535    */
536   shell_file = "csh";
537   if (path == NULL)
538     path = "/bin:/usr/bin";
539   tryname = alloca (strlen (path) + strlen (shell_file) + 2);
540   for (p = path; p != NULL; p = p1 ? p1 + 1: NULL)
541     {
542     p1 = strchr (p, ':');
543     if (p1 != NULL)
544       len = p1 - p;
545     else
546       len = strlen (p);
547     strncpy (tryname, p, len);
548     tryname[len] = '\0';
549     strcat (tryname, "/");
550     strcat (tryname, shell_file);
551     if (access (tryname, X_OK) < 0)
552       continue;
553     if (stat (tryname, &statbuf) < 0)
554       continue;
555     if (!S_ISREG (statbuf.st_mode))
556       /* We certainly need to reject directories.  I'm not quite
557          as sure about FIFOs, sockets, etc., but I kind of doubt
558          that people want to exec() these things.  */
559       continue;
560       break;
561     }
562   if (p == NULL)
563     /* Not found. I replaced the error() which existed in procfs.c
564      * with simply passing in NULL and hoping fork_inferior() 
565      * can deal with it. - RT
566      */ 
567     /* error ("Can't find shell %s in PATH", shell_file); */
568     shell_file = NULL;
569   else
570     shell_file = tryname;
571
572   fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, pre_fork_inferior, NULL);
573 #else
574  fork_inferior (exec_file, allargs, env, ptrace_me, ptrace_him, NULL, NULL);
575 #endif
576   /* We are at the first instruction we care about.  */
577   /* Pedal to the metal... */
578   proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
579 }
580
581 #if !defined(CHILD_POST_STARTUP_INFERIOR)
582 void
583 child_post_startup_inferior (pid)
584   int  pid;
585 {
586   /* This version of Unix doesn't require a meaningful "post startup inferior"
587      operation by a debugger.
588      */
589 }
590 #endif
591
592 #if !defined(CHILD_ACKNOWLEDGE_CREATED_INFERIOR)
593 void
594 child_acknowledge_created_inferior (pid)
595   int  pid;
596 {
597   /* This version of Unix doesn't require a meaningful "acknowledge created inferior"
598      operation by a debugger.
599      */
600 }
601 #endif
602
603
604 void
605 child_clone_and_follow_inferior (child_pid, followed_child)
606   int  child_pid;
607   int  *followed_child;
608 {
609   clone_and_follow_inferior (child_pid, followed_child);
610
611   /* Don't resume CHILD_PID; it's stopped where it ought to be, until
612      the decision gets made elsewhere how to continue it.
613      */
614 }
615
616
617 #if !defined(CHILD_POST_FOLLOW_INFERIOR_BY_CLONE)
618 void
619 child_post_follow_inferior_by_clone ()
620 {
621   /* This version of Unix doesn't require a meaningful "post follow inferior"
622      operation by a clone debugger.
623      */
624 }
625 #endif
626
627 #if !defined(CHILD_INSERT_FORK_CATCHPOINT)
628 int
629 child_insert_fork_catchpoint (pid)
630      int pid;
631 {
632   /* This version of Unix doesn't support notification of fork events.  */
633   return 0;
634 }
635 #endif
636
637 #if !defined(CHILD_REMOVE_FORK_CATCHPOINT)
638 int
639 child_remove_fork_catchpoint (pid)
640      int pid;
641 {
642   /* This version of Unix doesn't support notification of fork events.  */
643   return 0;
644 }
645 #endif
646
647 #if !defined(CHILD_INSERT_VFORK_CATCHPOINT)
648 int
649 child_insert_vfork_catchpoint (pid)
650      int pid;
651 {
652   /* This version of Unix doesn't support notification of vfork events.  */
653   return 0;
654 }
655 #endif
656
657 #if !defined(CHILD_REMOVE_VFORK_CATCHPOINT)
658 int
659 child_remove_vfork_catchpoint (pid)
660      int pid;
661 {
662   /* This version of Unix doesn't support notification of vfork events.  */
663   return 0;
664 }
665 #endif
666
667 #if !defined(CHILD_HAS_FORKED)
668 int
669 child_has_forked (pid, child_pid)
670      int pid;
671      int *child_pid;
672 {
673   /* This version of Unix doesn't support notification of fork events.  */
674   return 0;
675 }
676 #endif
677
678
679 #if !defined(CHILD_HAS_VFORKED)
680 int
681 child_has_vforked (pid, child_pid)
682   int  pid;
683   int *  child_pid;
684 {
685   /* This version of Unix doesn't support notification of vfork events.
686      */
687   return 0;
688 }
689 #endif
690
691
692 #if !defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
693 int
694 child_can_follow_vfork_prior_to_exec ()
695 {
696   /* This version of Unix doesn't support notification of vfork events.
697      However, if it did, it probably wouldn't allow vforks to be followed
698      before the following exec.
699      */
700   return 0;
701 }
702 #endif
703
704
705 #if !defined(CHILD_POST_FOLLOW_VFORK)
706 void
707 child_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child)
708   int  parent_pid;
709   int  followed_parent;
710   int  child_pid;
711   int  followed_child;
712 {
713   /* This version of Unix doesn't require a meaningful "post follow vfork"
714      operation by a clone debugger.
715      */
716 }
717 #endif
718
719 #if !defined(CHILD_INSERT_EXEC_CATCHPOINT)
720 int
721 child_insert_exec_catchpoint (pid)
722      int pid;
723 {
724   /* This version of Unix doesn't support notification of exec events.  */
725   return 0;
726 }
727 #endif
728
729 #if !defined(CHILD_REMOVE_EXEC_CATCHPOINT)
730 int
731 child_remove_exec_catchpoint (pid)
732      int pid;
733 {
734   /* This version of Unix doesn't support notification of exec events.  */
735   return 0;
736 }
737 #endif
738
739 #if !defined(CHILD_HAS_EXECD)
740 int
741 child_has_execd (pid, execd_pathname)
742   int  pid;
743   char **  execd_pathname;
744 {
745   /* This version of Unix doesn't support notification of exec events.
746      */
747   return 0;
748 }
749 #endif
750
751
752 #if !defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
753 int
754 child_reported_exec_events_per_exec_call ()
755 {
756   /* This version of Unix doesn't support notification of exec events.
757      */
758   return 1;
759 }
760 #endif
761
762
763 #if !defined(CHILD_HAS_SYSCALL_EVENT)
764 int
765 child_has_syscall_event (pid, kind, syscall_id)
766   int  pid;
767   enum target_waitkind *  kind;
768   int *  syscall_id;
769 {
770   /* This version of Unix doesn't support notification of syscall events.
771      */
772   return 0;
773 }
774 #endif
775
776
777 #if !defined(CHILD_HAS_EXITED)
778 int
779 child_has_exited (pid, wait_status, exit_status)
780   int  pid;
781   int  wait_status;
782   int *  exit_status;
783 {
784   if (WIFEXITED (wait_status))
785     {
786       *exit_status = WEXITSTATUS (wait_status);
787       return 1;
788     }
789
790   if (WIFSIGNALED (wait_status))
791     {
792       *exit_status = 0;  /* ?? Don't know what else to say here. */
793       return 1;
794     }
795
796   /* ?? Do we really need to consult the event state, too?  Assume the
797    wait_state alone suffices.
798    */
799   return 0;
800 }
801 #endif
802
803
804 static void
805 child_mourn_inferior ()
806 {
807   /* FIXME: Should be in a header file */
808   extern void proc_remove_foreign PARAMS ((int));
809
810   unpush_target (&child_ops);
811   proc_remove_foreign (inferior_pid);
812   generic_mourn_inferior ();
813 }
814
815 static int
816 child_can_run ()
817 {
818   /* This variable is controlled by modules that sit atop inftarg that may layer
819      their own process structure atop that provided here.  hpux-thread.c does
820      this because of the Hpux user-mode level thread model.  */
821
822   return !child_suppress_run;
823 }
824
825 /* Send a SIGINT to the process group.  This acts just like the user typed a
826    ^C on the controlling terminal.
827
828    XXX - This may not be correct for all systems.  Some may want to use
829    killpg() instead of kill (-pgrp). */
830
831 static void
832 child_stop ()
833 {
834   extern pid_t inferior_process_group;
835
836   kill (-inferior_process_group, SIGINT);
837 }
838
839 #if !defined(CHILD_ENABLE_EXCEPTION_CALLBACK)
840 struct symtab_and_line *
841 child_enable_exception_callback (kind, enable)
842   enum exception_event_kind kind;
843   int enable;
844 {
845   return (struct symtab_and_line *) NULL;
846 }
847 #endif
848
849 #if !defined(CHILD_GET_CURRENT_EXCEPTION_EVENT)
850 struct exception_event_record *
851 child_get_current_exception_event ()
852 {
853   return (struct exception_event_record *) NULL;
854 }
855 #endif
856
857
858 #if !defined(CHILD_PID_TO_EXEC_FILE)
859 char *
860 child_pid_to_exec_file (pid)
861   int  pid;
862 {
863   /* This version of Unix doesn't support translation of a process ID
864      to the filename of the executable file.
865      */
866   return NULL;
867 }
868 #endif
869
870 char *
871 child_core_file_to_sym_file (core)
872   char *  core;
873 {
874   /* The target stratum for a running executable need not support
875      this operation.
876      */
877   return NULL;
878 }
879
880
881 \f
882 static void
883 init_child_ops ()
884 {
885   child_ops.to_shortname = "child";
886   child_ops.to_longname = "Unix child process";
887   child_ops.to_doc = "Unix child process (started by the \"run\" command).";
888   child_ops.to_open = child_open;
889   child_ops.to_attach = child_attach;
890   child_ops.to_post_attach = child_post_attach;
891   child_ops.to_require_attach = child_require_attach;
892   child_ops.to_detach = child_detach;
893   child_ops.to_require_detach = child_require_detach;
894   child_ops.to_resume = child_resume;
895   child_ops.to_wait = child_wait;
896   child_ops.to_post_wait = child_post_wait;
897   child_ops.to_fetch_registers = fetch_inferior_registers;
898   child_ops.to_store_registers = store_inferior_registers;
899   child_ops.to_prepare_to_store = child_prepare_to_store;
900   child_ops.to_xfer_memory = child_xfer_memory;
901   child_ops.to_files_info = child_files_info;
902   child_ops.to_insert_breakpoint = memory_insert_breakpoint;
903   child_ops.to_remove_breakpoint = memory_remove_breakpoint;
904   child_ops.to_terminal_init = terminal_init_inferior;
905   child_ops.to_terminal_inferior = terminal_inferior;
906   child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
907   child_ops.to_terminal_ours = terminal_ours;
908   child_ops.to_terminal_info = child_terminal_info;
909   child_ops.to_kill = kill_inferior;
910   child_ops.to_create_inferior = child_create_inferior;
911   child_ops.to_post_startup_inferior = child_post_startup_inferior;
912   child_ops.to_acknowledge_created_inferior = child_acknowledge_created_inferior;
913   child_ops.to_clone_and_follow_inferior = child_clone_and_follow_inferior;
914   child_ops.to_post_follow_inferior_by_clone = child_post_follow_inferior_by_clone;
915   child_ops.to_insert_fork_catchpoint = child_insert_fork_catchpoint;
916   child_ops.to_remove_fork_catchpoint = child_remove_fork_catchpoint;
917   child_ops.to_insert_vfork_catchpoint = child_insert_vfork_catchpoint;
918   child_ops.to_remove_vfork_catchpoint = child_remove_vfork_catchpoint;
919   child_ops.to_has_forked = child_has_forked;
920   child_ops.to_has_vforked = child_has_vforked;
921   child_ops.to_can_follow_vfork_prior_to_exec = child_can_follow_vfork_prior_to_exec;
922   child_ops.to_post_follow_vfork = child_post_follow_vfork;
923   child_ops.to_insert_exec_catchpoint = child_insert_exec_catchpoint;
924   child_ops.to_remove_exec_catchpoint = child_remove_exec_catchpoint;
925   child_ops.to_has_execd = child_has_execd;
926   child_ops.to_reported_exec_events_per_exec_call = child_reported_exec_events_per_exec_call;
927   child_ops.to_has_syscall_event = child_has_syscall_event;
928   child_ops.to_has_exited = child_has_exited;
929   child_ops.to_mourn_inferior = child_mourn_inferior;
930   child_ops.to_can_run = child_can_run;
931   child_ops.to_thread_alive = child_thread_alive;
932   child_ops.to_stop = child_stop;
933   child_ops.to_enable_exception_callback = child_enable_exception_callback;
934   child_ops.to_get_current_exception_event = child_get_current_exception_event;
935   child_ops.to_pid_to_exec_file = child_pid_to_exec_file;
936   child_ops.to_core_file_to_sym_file = child_core_file_to_sym_file;
937   child_ops.to_stratum = process_stratum;
938   child_ops.to_has_all_memory = 1;
939   child_ops.to_has_memory = 1;
940   child_ops.to_has_stack = 1;
941   child_ops.to_has_registers = 1;
942   child_ops.to_has_execution = 1;
943   child_ops.to_magic = OPS_MAGIC;
944 }
945
946 void
947 _initialize_inftarg ()
948 {
949 #ifdef HAVE_OPTIONAL_PROC_FS
950   char procname[32];
951   int fd;
952
953   /* If we have an optional /proc filesystem (e.g. under OSF/1),
954      don't add ptrace support if we can access the running GDB via /proc.  */
955 #ifndef PROC_NAME_FMT
956 #define PROC_NAME_FMT "/proc/%05d"
957 #endif
958   sprintf (procname, PROC_NAME_FMT, getpid ());
959   if ((fd = open (procname, O_RDONLY)) >= 0)
960     {
961       close (fd);
962       return;
963     }
964 #endif
965
966   init_child_ops ();
967   add_target (&child_ops);
968 }