* fork-child.c, inferior.h (fork_inferior): New argument shell_file.

* procfs.c (procfs_create_inferior), inftarg.c (child_create_inferior),
	m3-nat.c (m3_create_inferior): Pass it.
	* procfs.c: Remove ptrace function.  It was declared in a way which
	conflicted with the prototype in unistd.h on Solaris.
This commit is contained in:
Jim Kingdon 1994-01-22 17:36:41 +00:00
parent ad9f5e78b8
commit 08f74b9271
4 changed files with 96 additions and 41 deletions

View file

@ -1,3 +1,11 @@
Sat Jan 22 08:30:42 1994 Jim Kingdon (kingdon@deneb.cygnus.com)
* fork-child.c, inferior.h (fork_inferior): New argument shell_file.
* procfs.c (procfs_create_inferior), inftarg.c (child_create_inferior),
m3-nat.c (m3_create_inferior): Pass it.
* procfs.c: Remove ptrace function. It was declared in a way which
conflicted with the prototype in unistd.h on Solaris.
Sat Jan 22 01:37:40 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de)
* sparc-tdep.c (frame_saved_pc): Get the pc from the saved pc

View file

@ -38,26 +38,28 @@ extern int original_stack_limit;
extern char **environ;
/* Start an inferior Unix child process and sets inferior_pid to its pid.
EXEC_FILE is the file to run.
ALLARGS is a string containing the arguments to the program.
ENV is the environment vector to pass. Errors reported with error(). */
#ifndef SHELL_FILE
#define SHELL_FILE "/bin/sh"
#endif
/* Start an inferior Unix child process and sets inferior_pid to its pid.
EXEC_FILE is the file to run.
ALLARGS is a string containing the arguments to the program.
ENV is the environment vector to pass. SHELL_FILE is the shell file,
or NULL if we should pick one. Errors reported with error(). */
void
fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
shell_file)
char *exec_file;
char *allargs;
char **env;
void (*traceme_fun) PARAMS ((void));
void (*init_trace_fun) PARAMS ((int));
char *shell_file;
{
int pid;
char *shell_command;
char *shell_file;
static char default_shell_file[] = SHELL_FILE;
int len;
/* Set debug_fork then attach to the child while it sleeps, to debug. */
@ -76,8 +78,10 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
the program to behave the same way as if run from
his/her favorite shell. So we let the shell run it for us.
FIXME-maybe, we might want a "set shell" command so the user can change
the shell from within GDB. */
shell_file = getenv ("SHELL");
the shell from within GDB (if so, change callers which pass in a non-NULL
shell_file too). */
if (shell_file == NULL)
shell_file = getenv ("SHELL");
if (shell_file == NULL)
shell_file = default_shell_file;

View file

@ -3879,7 +3879,7 @@ m3_create_inferior (exec_file, allargs, env)
char *allargs;
char **env;
{
fork_inferior (exec_file, allargs, env, m3_trace_m3, m3_trace_him);
fork_inferior (exec_file, allargs, env, m3_trace_m3, m3_trace_him, NULL);
/* We are at the first instruction we care about. */
/* Pedal to the metal... */
proceed ((CORE_ADDR) -1, 0, 0);

View file

@ -34,6 +34,7 @@ regardless of whether or not the actual target has floating point hardware.
#include "defs.h"
#include <sys/types.h>
#include <time.h>
#include <sys/procfs.h>
#include <fcntl.h>
@ -41,6 +42,8 @@ regardless of whether or not the actual target has floating point hardware.
#include <string.h>
#include <stropts.h>
#include <poll.h>
#include <unistd.h>
#include <sys/stat.h>
#include "inferior.h"
#include "target.h"
@ -1206,36 +1209,6 @@ init_syscall_table ()
/*
GLOBAL FUNCTION
ptrace -- override library version to force errors for /proc version
SYNOPSIS
int ptrace (int request, int pid, PTRACE_ARG3_TYPE arg3, int arg4)
DESCRIPTION
When gdb is configured to use /proc, it should not be calling
or otherwise attempting to use ptrace. In order to catch errors
where use of /proc is configured, but some routine is still calling
ptrace, we provide a local version of a function with that name
that does nothing but issue an error message.
*/
int
ptrace (request, pid, arg3, arg4)
int request;
int pid;
PTRACE_ARG3_TYPE arg3;
int arg4;
{
error ("internal error - there is a call to ptrace() somewhere");
/*NOTREACHED*/
}
/*
LOCAL FUNCTION
procfs_kill_inferior - kill any currently inferior
@ -3448,8 +3421,78 @@ procfs_create_inferior (exec_file, allargs, env)
char *allargs;
char **env;
{
char *shell_file = getenv ("SHELL");
char *tryname;
if (shell_file != NULL && strchr (shell_file, '/') == NULL)
{
/* We will be looking down the PATH to find shell_file. If we
just do this the normal way (via execlp, which operates by
attempting an exec for each element of the PATH until it
finds one which succeeds), then there will be an exec for
each failed attempt, each of which will cause a PR_SYSEXIT
stop, and we won't know how to distinguish the PR_SYSEXIT's
for these failed execs with the ones for successful execs
(whether the exec has succeeded is stored at that time in the
carry bit or some such architecture-specific and
non-ABI-specified place).
So I can't think of anything better than to search the PATH
now. This has several disadvantages: (1) There is a race
condition; if we find a file now and it is deleted before we
exec it, we lose, even if the deletion leaves a valid file
further down in the PATH, (2) there is no way to know exactly
what an executable (in the sense of "capable of being
exec'd") file is. Using access() loses because it may lose
if the caller is the superuser; failing to use it loses if
there are ACLs or some such. */
char *p;
char *p1;
/* FIXME-maybe: might want "set path" command to replace putenv hack
in set_in_environ. */
char *path = getenv ("PATH");
int len;
struct stat statbuf;
if (path == NULL)
path = "/bin:/usr/bin";
tryname = alloca (strlen (path) + strlen (shell_file) + 2);
for (p = path; p != NULL; p = p1 ? p1 + 1: NULL)
{
p1 = strchr (p, ':');
if (p1 != NULL)
len = p1 - p;
else
len = strlen (p);
strncpy (tryname, p, len);
tryname[len] = '\0';
strcat (tryname, "/");
strcat (tryname, shell_file);
if (access (tryname, X_OK) < 0)
continue;
if (stat (tryname, &statbuf) < 0)
continue;
if (!S_ISREG (statbuf.st_mode))
/* We certainly need to reject directories. I'm not quite
as sure about FIFOs, sockets, etc., but I kind of doubt
that people want to exec() these things. */
continue;
break;
}
if (p == NULL)
/* Not found. This must be an error rather than merely passing
the file to execlp(), because execlp() would try all the
exec()s, causing GDB to get confused. */
error ("Can't find shell %s in PATH", shell_file);
shell_file = tryname;
}
fork_inferior (exec_file, allargs, env,
proc_set_exec_trap, procfs_init_inferior);
proc_set_exec_trap, procfs_init_inferior, shell_file);
/* We are at the first instruction we care about. */
/* Pedal to the metal... */