Implement AT_EACCESS
authorDavid Bartley <dtbartle@glibc.(none)>
Mon, 2 Feb 2009 07:53:45 +0000 (07:53 +0000)
committerDavid Bartley <dtbartle@glibc.(none)>
Mon, 2 Feb 2009 07:53:45 +0000 (07:53 +0000)
sysdeps/unix/sysv/solaris2/kopensolaris-gnu/Makefile
sysdeps/unix/sysv/solaris2/kopensolaris-gnu/bits/fcntl.h
sysdeps/unix/sysv/solaris2/kopensolaris-gnu/faccessat.c [new file with mode: 0644]
sysdeps/unix/sysv/solaris2/kopensolaris-gnu/syscalls.list

index e053824..11d0f3a 100644 (file)
@@ -10,7 +10,7 @@ ifeq ($(subdir),io)
 sysdep_routines += sys_open sys_open64 sys_openat sys_openat64 \
     sys_fstat sys_fstat64 sys_fstatat sys_fstatat64 sys_lstat \
     sys_lstat64 sys_stat sys_stat64 sys_sendfilev sys_sendfilev64 \
-    sys_getcwd sys_pipe sys_mknod sys_access
+    sys_getcwd sys_pipe sys_mknod sys_access sys_accessat
 headers := $(filter-out sys/vfs.h, $(headers))
 endif
 
index b4ca3ac..de49941 100644 (file)
@@ -217,12 +217,14 @@ typedef struct flock64
 /* at-file support */
 #ifdef __USE_ATFILE
 # define __AT_DEFINED
-# define AT_FDCWD              0xffd19553   /* Special value used to indicate
-                                          the *at functions should use the
-                                          current working directory. */
-# define AT_SYMLINK_NOFOLLOW   0x1000  /* Do not follow symbolic links.  */
-# define AT_REMOVEDIR          0x1     /* Remove directory instead of
-                                          unlinking file.  */
+# define AT_FDCWD      0xffd19553      /* Special value used to indicate
+                                          the *at functions should use the
+                                          current working directory. */
+# define AT_SYMLINK_NOFOLLOW   0x1000  /* Do not follow symbolic links.  */
+# define AT_REMOVEDIR          0x1     /* Remove directory instead of
+                                          unlinking file.  */
+# define AT_EACCESS            010     /* Test access permitted for
+                                          effective IDs, not real IDs.  */
 #endif
 
 /* Define some more compatibility macros to be backward compatible with
diff --git a/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/faccessat.c b/sysdeps/unix/sysv/solaris2/kopensolaris-gnu/faccessat.c
new file mode 100644 (file)
index 0000000..9648352
--- /dev/null
@@ -0,0 +1,107 @@
+/* Test for access to file, relative to open directory.  OpenSolaris version.
+   Copyright (C) 2006, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   OpenSolaris bits contributed by David Bartley
+    <dtbartle@csclub.uwaterloo.ca>, 2009.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stddef.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#define E_OK 010
+
+DECLARE_INLINE_SYSCALL (int, accessat, int, const char *, int);
+
+int
+faccessat (fd, file, type, flag)
+     int fd;
+     const char *file;
+     int type;
+     int flag;
+{
+  if (file == NULL || (flag & ~(AT_EACCESS)) != 0
+      || (type & ~(R_OK|W_OK|X_OK|F_OK|E_OK)) != 0)
+    {
+      __set_errno (EINVAL);
+      return -1;
+    }
+
+  if (fd < 0 && fd != AT_FDCWD)
+    {
+      __set_errno (EBADF);
+      return -1;
+    }
+
+  if (flag & AT_EACCESS)
+    {
+      type |= E_OK;
+    }
+
+  int res = INLINE_SYSCALL (accessat, 3, fd, file, type);
+
+  /* XXX: This should really be fixed in the kernel.  */
+  if (res == 0 && (type & X_OK))
+    {
+      uid_t uid;
+      gid_t gid;
+
+      uid = (type & E_OK) ? geteuid () : getuid ();
+      gid = (type & E_OK) ? getegid () : getgid ();
+      if (uid == 0 || gid == 0)
+        {
+          struct stat buf;
+
+          if (fstatat (fd, file, &buf, 0) != 0)
+            return -1;
+
+          /* Test user bit.  */
+          if (uid == buf.st_uid)
+            {
+              if ((buf.st_mode & S_IXUSR) == 0)
+                {
+                  __set_errno (EACCES);
+                  return -1;
+                }
+              return 0;
+            }
+
+          /* Test gid bit.  */
+          if (gid == buf.st_gid)
+            {
+              if ((buf.st_mode & S_IXGRP) == 0)
+                {
+                  __set_errno (EACCES);
+                  return -1;
+                }
+              return 0;
+            }
+
+          /* Test other bit.  */
+          if ((buf.st_mode & S_IXOTH) == 0)
+            {
+              __set_errno (EACCES);
+              return -1;
+            }
+          return 0;
+        }
+    }
+
+  return res;
+}
index 9ae3c21..3595888 100644 (file)
@@ -96,7 +96,6 @@ putacct             - exacctsys:putacct     i:iipii     putacct
 wracct              - exacctsys:wracct      i:iii       wracct
 
 # *at
-faccessat           - fsat:accessat         i:isi       faccessat
 fchownat            - fsat:fchownat         i:isiii     fchownat
 futimesat           - fsat:futimesat        i:isi       futimesat
 renameat            - fsat:renameat         i:isis      renameat
@@ -183,6 +182,7 @@ is_system_labeled   - labelsys:syslabeling  i:          is_system_labeled
 #
 
 sys_access          - access                i:si        __syscall_access
+sys_accessat        - fsat:accessat         i:isi       __syscall_accessat
 sys_allocids        - sidsys:allocids       i:iii       __syscall_allocids
 sys_brk             - brk                   i:p         __syscall_brk
 sys_fcntl           - fcntl                 Ri:iiF      __syscall_fcntl