aboutsummaryrefslogtreecommitdiff
path: root/gdb/procfs.c
diff options
context:
space:
mode:
authorJim Kingdon <jkingdon@engr.sgi.com>1994-01-22 17:36:41 +0000
committerJim Kingdon <jkingdon@engr.sgi.com>1994-01-22 17:36:41 +0000
commit08f74b9271bc22a0e0a55707f18b23778d25be1e (patch)
tree99644d884730208f4aa745688add3ca311b6238b /gdb/procfs.c
parentad9f5e78b81cfeb4c6eda5118cae093e9221db6a (diff)
downloadgdb-08f74b9271bc22a0e0a55707f18b23778d25be1e.zip
gdb-08f74b9271bc22a0e0a55707f18b23778d25be1e.tar.gz
gdb-08f74b9271bc22a0e0a55707f18b23778d25be1e.tar.bz2
* 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.
Diffstat (limited to 'gdb/procfs.c')
-rw-r--r--gdb/procfs.c105
1 files changed, 74 insertions, 31 deletions
diff --git a/gdb/procfs.c b/gdb/procfs.c
index c9e0d8f..0d7aee8 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -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... */