NEWS.stable: log cherry-pick [e446f25]->[c092018] relocatable-shell: Update suggested...
[gnulib.git] / lib / euidaccess.c
index 978ab56..363e6fe 100644 (file)
@@ -1,53 +1,41 @@
 /* euidaccess -- check if effective user id can access file
 
-   Copyright (C) 1990, 1991, 1995, 1998, 2000, 2003, 2004 Free
+   Copyright (C) 1990-1991, 1995, 1998, 2000, 2003-2006, 2008-2014 Free
    Software Foundation, Inc.
 
    This file is part of the GNU C Library.
 
-   This program is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
-   You should have received a copy of the GNU General Public License along
-   with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 /* Written by David MacKenzie and Torbjorn Granlund.
    Adapted for GNU C library by Roland McGrath.  */
 
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
 #ifndef _LIBC
-# include "euidaccess.h"
+# include <config.h>
 #endif
 
+#include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
-#if HAVE_UNISTD_H || defined _LIBC
-# include <unistd.h>
-#endif
+#include "root-uid.h"
 
 #if HAVE_LIBGEN_H
 # include <libgen.h>
 #endif
 
-#ifndef _POSIX_VERSION
-uid_t getuid ();
-gid_t getgid ();
-uid_t geteuid ();
-gid_t getegid ();
-#endif
-
 #include <errno.h>
 #ifndef __set_errno
 # define __set_errno(val) errno = (val)
@@ -77,29 +65,26 @@ gid_t getegid ();
 # undef stat
 # define stat stat64
 
-#else
-
-# include "group-member.h"
-# include "stat-macros.h"
-
 #endif
 
-/* Return 0 if the user has permission of type MODE on file PATH;
-   otherwise, return -1 and set `errno'.
+/* Return 0 if the user has permission of type MODE on FILE;
+   otherwise, return -1 and set 'errno'.
    Like access, except that it uses the effective user and group
    id's instead of the real ones, and it does not always check for read-only
    file system, text busy, etc.  */
 
 int
-euidaccess (const char *path, int mode)
+euidaccess (const char *file, int mode)
 {
-#if defined EFF_ONLY_OK
-  return access (path, mode | EFF_ONLY_OK);
-#elif defined ACC_SELF
-  return accessx (path, mode, ACC_SELF);
-#elif HAVE_EACCESS
-  return eaccess (path, mode);
-#else
+#if HAVE_FACCESSAT                   /* glibc, AIX 7, Solaris 11, Cygwin 1.7 */
+  return faccessat (AT_FDCWD, file, mode, AT_EACCESS);
+#elif defined EFF_ONLY_OK               /* IRIX, OSF/1, Interix */
+  return access (file, mode | EFF_ONLY_OK);
+#elif defined ACC_SELF                  /* AIX */
+  return accessx (file, mode, ACC_SELF);
+#elif HAVE_EACCESS                      /* FreeBSD */
+  return eaccess (file, mode);
+#else       /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, mingw, BeOS */
 
   uid_t uid = getuid ();
   gid_t gid = getgid ();
@@ -117,25 +102,25 @@ euidaccess (const char *path, int mode)
      safe.  */
 
   if (mode == F_OK)
-    return stat (path, &stats);
+    return stat (file, &stats);
   else
     {
       int result;
       int saved_errno;
 
       if (uid != euid)
-       setreuid (euid, uid);
+        setreuid (euid, uid);
       if (gid != egid)
-       setregid (egid, gid);
+        setregid (egid, gid);
 
-      result = access (path, mode);
+      result = access (file, mode);
       saved_errno = errno;
 
       /* Restore them.  */
       if (uid != euid)
-       setreuid (uid, euid);
+        setreuid (uid, euid);
       if (gid != egid)
-       setregid (gid, egid);
+        setregid (gid, egid);
 
       errno = saved_errno;
       return result;
@@ -150,15 +135,16 @@ euidaccess (const char *path, int mode)
   unsigned int granted;
   if (uid == euid && gid == egid)
     /* If we are not set-uid or set-gid, access does the same.  */
-    return access (path, mode);
+    return access (file, mode);
 
-  if (stat (path, &stats))
+  if (stat (file, &stats) != 0)
     return -1;
 
   /* The super-user can read and write any file, and execute any file
      that anyone can execute.  */
-  if (euid == 0 && ((mode & X_OK) == 0
-                   || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
+  if (euid == ROOT_UID
+      && ((mode & X_OK) == 0
+          || (stats.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
     return 0;
 
   /* Convert the mode to traditional form, clearing any bogus bits.  */
@@ -166,11 +152,11 @@ euidaccess (const char *path, int mode)
     mode &= 7;
   else
     mode = ((mode & R_OK ? 4 : 0)
-           + (mode & W_OK ? 2 : 0)
-           + (mode & X_OK ? 1 : 0));
+            + (mode & W_OK ? 2 : 0)
+            + (mode & X_OK ? 1 : 0));
 
   if (mode == 0)
-    return 0;                  /* The file exists.  */
+    return 0;                   /* The file exists.  */
 
   /* Convert the file's permission bits to traditional form.  */
   if (S_IRUSR == (4 << 6) && S_IWUSR == (2 << 6) && S_IXUSR == (1 << 6)
@@ -179,14 +165,14 @@ euidaccess (const char *path, int mode)
     granted = stats.st_mode;
   else
     granted = ((stats.st_mode & S_IRUSR ? 4 << 6 : 0)
-              + (stats.st_mode & S_IWUSR ? 2 << 6 : 0)
-              + (stats.st_mode & S_IXUSR ? 1 << 6 : 0)
-              + (stats.st_mode & S_IRGRP ? 4 << 3 : 0)
-              + (stats.st_mode & S_IWGRP ? 2 << 3 : 0)
-              + (stats.st_mode & S_IXGRP ? 1 << 3 : 0)
-              + (stats.st_mode & S_IROTH ? 4 << 0 : 0)
-              + (stats.st_mode & S_IWOTH ? 2 << 0 : 0)
-              + (stats.st_mode & S_IXOTH ? 1 << 0 : 0));
+               + (stats.st_mode & S_IWUSR ? 2 << 6 : 0)
+               + (stats.st_mode & S_IXUSR ? 1 << 6 : 0)
+               + (stats.st_mode & S_IRGRP ? 4 << 3 : 0)
+               + (stats.st_mode & S_IWGRP ? 2 << 3 : 0)
+               + (stats.st_mode & S_IXGRP ? 1 << 3 : 0)
+               + (stats.st_mode & S_IROTH ? 4 << 0 : 0)
+               + (stats.st_mode & S_IWOTH ? 2 << 0 : 0)
+               + (stats.st_mode & S_IXOTH ? 1 << 0 : 0));
 
   if (euid == stats.st_uid)
     granted >>= 6;