-/* 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
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)
len = strlen (file) + 1;
name = __alloca (strlen (path) + len);
- uid = geteuid ();
- gid = getegid ();
- ngroups = getgroups (sizeof (groups) / sizeof (groups[0]), groups);
p = path;
do
{
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;
}