* posix/execvp.c: Don't use stat to search path; just try execv

until it works.
This commit is contained in:
Roland McGrath 1995-04-03 09:00:10 +00:00
parent e607b492e5
commit c4bf5a3e9a
2 changed files with 25 additions and 45 deletions

View File

@ -1,5 +1,8 @@
Sun Apr 2 13:13:52 1995 Roland McGrath <roland@churchy.gnu.ai.mit.edu>
* posix/execvp.c: Don't use stat to search path; just try execv
until it works.
* sysdeps/mach/hurd/i386/trampoline.c: Add a link to
SS->active_resources, so that _hurdsig_longjmp_from_handler will
be called when a longjmp unwinds the signal frame.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -16,34 +16,25 @@ License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <limits.h>
#include <sys/types.h>
#ifndef HAVE_GNU_LD
#define __environ environ
#endif
/* Execute FILE, searching in the `PATH' environment variable if it contains
no slashes, with arguments ARGV and environment from `environ'. */
int
DEFUN(execvp, (file, argv), CONST char *file AND char *CONST argv[])
execvp (file, argv)
const char *file;
char *const argv[];
{
if (strchr (file, '/') == NULL)
if (strchr (file, '/') != NULL)
/* Don't search when it contains a slash. */
return execv (file, argv);
else
{
char *path, *p;
struct stat st;
char *path, *p, *name;
size_t len;
uid_t uid;
gid_t gid;
int ngroups;
gid_t groups[NGROUPS_MAX];
char *name;
path = getenv ("PATH");
if (path == NULL)
@ -59,9 +50,6 @@ DEFUN(execvp, (file, argv), CONST char *file AND char *CONST argv[])
len = strlen (file) + 1;
name = __alloca (strlen (path) + len);
uid = geteuid ();
gid = getegid ();
ngroups = getgroups (sizeof (groups) / sizeof (groups[0]), groups);
p = path;
do
{
@ -81,32 +69,21 @@ DEFUN(execvp, (file, argv), CONST char *file AND char *CONST argv[])
name[p - path] = '/';
(void) memcpy (&name[(p - path) + 1], file, len);
}
if (stat (name, &st) == 0 && S_ISREG (st.st_mode))
{
int bit = S_IXOTH;
if (st.st_uid == uid)
bit = S_IXUSR;
else if (st.st_gid == gid)
bit = S_IXGRP;
else
{
register int i;
for (i = 0; i < ngroups; ++i)
if (st.st_gid == groups[i])
{
bit = S_IXGRP;
break;
}
}
if (st.st_mode & bit)
{
file = name;
break;
}
}
/* Try to execute this name. If it works, execv will not return. */
execv (name, argv);
if (errno != ENOENT && errno != EACCES)
/* Those errors indicate the file is missing or not executable
by us, in which case we want to just try the next path
directory. Some other error means we found an executable
file, but something went wrong executing it; return the
error to our caller. */
return -1;
}
while (*p++ != '\0');
}
return __execve (file, argv, __environ);
/* We tried every element and none of them worked.
Return the error from the last attempt (probably ENOENT). */
return -1;
}