+ int should_resume = 1;
+ struct thread_info *tp;
+
+ /* Copy user stepping state to the new inferior thread. FIXME: the
+ followed fork child thread should have a copy of most of the
+ parent thread structure's run control related fields, not just these.
+ Initialized to avoid "may be used uninitialized" warnings from gcc. */
+ struct breakpoint *step_resume_breakpoint = NULL;
+ CORE_ADDR step_range_start = 0;
+ CORE_ADDR step_range_end = 0;
+ struct frame_id step_frame_id = { 0 };
+
+ if (!non_stop)
+ {
+ ptid_t wait_ptid;
+ struct target_waitstatus wait_status;
+
+ /* Get the last target status returned by target_wait(). */
+ get_last_target_status (&wait_ptid, &wait_status);
+
+ /* If not stopped at a fork event, then there's nothing else to
+ do. */
+ if (wait_status.kind != TARGET_WAITKIND_FORKED
+ && wait_status.kind != TARGET_WAITKIND_VFORKED)
+ return 1;
+
+ /* Check if we switched over from WAIT_PTID, since the event was
+ reported. */
+ if (!ptid_equal (wait_ptid, minus_one_ptid)
+ && !ptid_equal (inferior_ptid, wait_ptid))
+ {
+ /* We did. Switch back to WAIT_PTID thread, to tell the
+ target to follow it (in either direction). We'll
+ afterwards refuse to resume, and inform the user what
+ happened. */
+ switch_to_thread (wait_ptid);
+ should_resume = 0;
+ }
+ }
+
+ tp = inferior_thread ();
+
+ /* If there were any forks/vforks that were caught and are now to be
+ followed, then do so now. */
+ switch (tp->pending_follow.kind)
+ {
+ case TARGET_WAITKIND_FORKED:
+ case TARGET_WAITKIND_VFORKED:
+ {
+ ptid_t parent, child;
+
+ /* If the user did a next/step, etc, over a fork call,
+ preserve the stepping state in the fork child. */
+ if (follow_child && should_resume)
+ {
+ step_resume_breakpoint
+ = clone_momentary_breakpoint (tp->step_resume_breakpoint);
+ step_range_start = tp->step_range_start;
+ step_range_end = tp->step_range_end;
+ step_frame_id = tp->step_frame_id;
+
+ /* For now, delete the parent's sr breakpoint, otherwise,
+ parent/child sr breakpoints are considered duplicates,
+ and the child version will not be installed. Remove
+ this when the breakpoints module becomes aware of
+ inferiors and address spaces. */
+ delete_step_resume_breakpoint (tp);
+ tp->step_range_start = 0;
+ tp->step_range_end = 0;
+ tp->step_frame_id = null_frame_id;
+ }
+
+ parent = inferior_ptid;
+ child = tp->pending_follow.value.related_pid;