* 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> 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 * sysdeps/mach/hurd/i386/trampoline.c: Add a link to
SS->active_resources, so that _hurdsig_longjmp_from_handler will SS->active_resources, so that _hurdsig_longjmp_from_handler will
be called when a longjmp unwinds the signal frame. 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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, not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */ Cambridge, MA 02139, USA. */
#include <ansidecl.h>
#include <unistd.h> #include <unistd.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.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 /* Execute FILE, searching in the `PATH' environment variable if it contains
no slashes, with arguments ARGV and environment from `environ'. */ no slashes, with arguments ARGV and environment from `environ'. */
int 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; char *path, *p, *name;
struct stat st;
size_t len; size_t len;
uid_t uid;
gid_t gid;
int ngroups;
gid_t groups[NGROUPS_MAX];
char *name;
path = getenv ("PATH"); path = getenv ("PATH");
if (path == NULL) if (path == NULL)
@ -59,9 +50,6 @@ DEFUN(execvp, (file, argv), CONST char *file AND char *CONST argv[])
len = strlen (file) + 1; len = strlen (file) + 1;
name = __alloca (strlen (path) + len); name = __alloca (strlen (path) + len);
uid = geteuid ();
gid = getegid ();
ngroups = getgroups (sizeof (groups) / sizeof (groups[0]), groups);
p = path; p = path;
do do
{ {
@ -81,32 +69,21 @@ DEFUN(execvp, (file, argv), CONST char *file AND char *CONST argv[])
name[p - path] = '/'; name[p - path] = '/';
(void) memcpy (&name[(p - path) + 1], file, len); (void) memcpy (&name[(p - path) + 1], file, len);
} }
if (stat (name, &st) == 0 && S_ISREG (st.st_mode))
{ /* Try to execute this name. If it works, execv will not return. */
int bit = S_IXOTH; execv (name, argv);
if (st.st_uid == uid) if (errno != ENOENT && errno != EACCES)
bit = S_IXUSR; /* Those errors indicate the file is missing or not executable
else if (st.st_gid == gid) by us, in which case we want to just try the next path
bit = S_IXGRP; directory. Some other error means we found an executable
else file, but something went wrong executing it; return the
{ error to our caller. */
register int i; return -1;
for (i = 0; i < ngroups; ++i)
if (st.st_gid == groups[i])
{
bit = S_IXGRP;
break;
}
}
if (st.st_mode & bit)
{
file = name;
break;
}
}
} }
while (*p++ != '\0'); 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;
} }