- /* It is generally good practice to flush any possible pending stdio
- output prior to doing a fork, to avoid the possibility of both the
- parent and child flushing the same data after the fork. */
-
- gdb_flush (gdb_stdout);
- gdb_flush (gdb_stderr);
-
- /* If there's any initialization of the target layers that must happen
- to prepare to handle the child we're about fork, do it now...
- */
- if (pre_trace_fun != NULL)
- (*pre_trace_fun) ();
-
- /* Create the child process. Note that the apparent call to vfork()
- below *might* actually be a call to fork() due to the fact that
- autoconf will ``#define vfork fork'' on certain platforms. */
- if (debug_fork)
- pid = fork ();
- else
- pid = vfork ();
-
- if (pid < 0)
- perror_with_name ("vfork");
-
- if (pid == 0)
- {
- if (debug_fork)
- sleep (debug_fork);
-
- /* Run inferior in a separate process group. */
- debug_setpgrp = gdb_setpgid ();
- if (debug_setpgrp == -1)
- perror ("setpgrp failed in child");
-
- /* Ask the tty subsystem to switch to the one we specified earlier
- (or to share the current terminal, if none was specified). */
-
- new_tty ();
-
- /* Changing the signal handlers for the inferior after
- a vfork can also change them for the superior, so we don't mess
- with signals here. See comments in
- initialize_signals for how we get the right signal handlers
- for the inferior. */
-
- /* "Trace me, Dr. Memory!" */
- (*traceme_fun) ();
- /* The call above set this process (the "child") as debuggable
- * by the original gdb process (the "parent"). Since processes
- * (unlike people) can have only one parent, if you are
- * debugging gdb itself (and your debugger is thus _already_ the
- * controller/parent for this child), code from here on out
- * is undebuggable. Indeed, you probably got an error message
- * saying "not parent". Sorry--you'll have to use print statements!
- */
-
- /* There is no execlpe call, so we have to set the environment
- for our child in the global variable. If we've vforked, this
- clobbers the parent, but environ is restored a few lines down
- in the parent. By the way, yes we do need to look down the
- path to find $SHELL. Rich Pixley says so, and I agree. */
- environ = env;
-
- /* If we decided above to start up with a shell,
- * we exec the shell,
- * "-c" says to interpret the next arg as a shell command
- * to execute, and this command is "exec <target-program> <args>".
- * "-f" means "fast startup" to the c-shell, which means
- * don't do .cshrc file. Doing .cshrc may cause fork/exec
- * events which will confuse debugger start-up code.
- */
- if (shell)
- {
- execlp (shell_file, shell_file, "-c", shell_command, (char *) 0);
-
- /* If we get here, it's an error */
- fprintf_unfiltered (gdb_stderr, "Cannot exec %s: %s.\n", shell_file,
- safe_strerror (errno));
- gdb_flush (gdb_stderr);
- _exit (0177);
- }
- else
- {
- /* Otherwise, we directly exec the target program with execvp. */
- int i;
- char *errstring;
-
- execvp (exec_file, argv);
-
- /* If we get here, it's an error */
- errstring = safe_strerror (errno);
- fprintf_unfiltered (gdb_stderr, "Cannot exec %s ", exec_file);
-
- i = 1;
- while (argv[i] != NULL)
- {
- if (i != 1)
- fprintf_unfiltered (gdb_stderr, " ");
- fprintf_unfiltered (gdb_stderr, "%s", argv[i]);
- i++;
- }
- fprintf_unfiltered (gdb_stderr, ".\n");
- /* This extra info seems to be useless
- fprintf_unfiltered (gdb_stderr, "Got error %s.\n", errstring);
- */
- gdb_flush (gdb_stderr);
- _exit (0177);
- }
- }
-
- /* Restore our environment in case a vforked child clob'd it. */
- environ = save_our_env;
-
- init_thread_list ();
-
- inferior_ptid = pid_to_ptid (pid); /* Needed for wait_for_inferior stuff below */