Skip to content

Commit

Permalink
* posix/execvp.c: Don't use stat to search path; just try execv
Browse files Browse the repository at this point in the history
 	until it works.
  • Loading branch information
Roland McGrath committed Apr 3, 1995
1 parent e607b49 commit c4bf5a3
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 45 deletions.
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
67 changes: 22 additions & 45 deletions posix/execvp.c
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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)
Expand All @@ -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
{
Expand All @@ -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;
}

0 comments on commit c4bf5a3

Please sign in to comment.