faccessat: new module
authorEric Blake <ebb9@byu.net>
Thu, 3 Sep 2009 19:41:18 +0000 (13:41 -0600)
committerEric Blake <ebb9@byu.net>
Fri, 4 Sep 2009 03:20:52 +0000 (21:20 -0600)
* modules/faccessat: New file.
* lib/faccessat.m4: Likewise.
* m4/faccessat.m4 (gl_FUNC_FACCESSAT): Likewise.
* m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add witness.
* modules/unistd (Makefile.am): Use it.
* lib/unistd.in.h (faccessat): Declare it.
(F_OK, X_OK, W_OK, R_OK): Provide definitions.
* lib/fcntl.in.h (AT_SYMLINK_FOLLOW, AT_EACCESS): Likewise.
* MODULES.html.sh (File system functions): Mention it.
* doc/posix-functions/faccessat.texi (faccessat): Likewise.
* doc/posix-headers/fcntl.texi (fcntl.h): Likewise.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
MODULES.html.sh
doc/posix-functions/faccessat.texi
doc/posix-headers/fcntl.texi
lib/faccessat.c [new file with mode: 0644]
lib/fcntl.in.h
lib/unistd.in.h
m4/faccessat.m4 [new file with mode: 0644]
m4/unistd_h.m4
modules/faccessat [new file with mode: 0644]
modules/unistd

index 4358759..02e06bd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2009-09-03  Eric Blake  <ebb9@byu.net>
 
+       faccessat: new module
+       * modules/faccessat: New file.
+       * lib/faccessat.m4: Likewise.
+       * m4/faccessat.m4 (gl_FUNC_FACCESSAT): Likewise.
+       * m4/unistd_h.m4 (gl_UNISTD_H_DEFAULTS): Add witness.
+       * modules/unistd (Makefile.am): Use it.
+       * lib/unistd.in.h (faccessat): Declare it.
+       (F_OK, X_OK, W_OK, R_OK): Provide definitions.
+       * lib/fcntl.in.h (AT_SYMLINK_FOLLOW, AT_EACCESS): Likewise.
+       * MODULES.html.sh (File system functions): Mention it.
+       * doc/posix-functions/faccessat.texi (faccessat): Likewise.
+       * doc/posix-headers/fcntl.texi (fcntl.h): Likewise.
+
        euidaccess: prefer POSIX over non-standard implementation
        * m4/euidaccess.m4 (gl_PREREQ_EUIDACCESS): Check for faccessat.
        * lib/euidaccess.c (euidaccess): Use it if available.
index bcecc55..b60ef61 100755 (executable)
@@ -2452,6 +2452,7 @@ func_all_modules ()
   func_module dirfd
   func_module double-slash-root
   func_module euidaccess
+  func_module faccessat
   func_module fdopendir
   func_module file-type
   func_module fileblocks
index bf3335d..835a5d8 100644 (file)
@@ -4,16 +4,22 @@
 
 POSIX specification: @url{http://www.opengroup.org/onlinepubs/9699919799/functions/faccessat.html}
 
-Gnulib module: ---
+Gnulib module: faccessat
 
 Portability problems fixed by Gnulib:
 @itemize
+@item
+This function is missing on some platforms:
+glibc 2.3.6, MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX
+5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x, mingw,
+Interix 3.5, BeOS.
+However, the replacement does not always take into account ACLs.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
 @item
-This function is missing on some platforms:
-glibc 2.3.6, MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX
-5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin 1.5.x, mingw, Interix 3.5, BeOS.
+There is an inherent race between calling this function and performing
+some action based on the results; you should think twice before
+trusting this function in a set-uid or set-gid program.
 @end itemize
index 020586c..5cf86ee 100644 (file)
@@ -32,7 +32,8 @@ platforms:
 Solaris 10
 
 @item
-@samp{AT_FDCWD}, @samp{AT_SYMLINK_NOFOLLOW}, and @samp{AT_REMOVEDIR}
+@samp{AT_FDCWD}, @samp{AT_EACCESS}, @samp{AT_SYMLINK_NOFOLLOW},
+@samp{AT_SYMLINK_FOLLOW}, and @samp{AT_REMOVEDIR}
 are missing on some platforms.
 @end itemize
 
@@ -61,7 +62,4 @@ on some platforms.
 @samp{POSIX_FADV_NORMAL}, @samp{POSIX_FADV_RANDOM},
 @samp{POSIX_FADV_SEQUENTIAL}, and @samp{POSIX_FADV_WILLNEED} are not
 defined on some platforms.
-
-@item
-@samp{AT_EACCESS} and @samp{AT_SYMLINK_FOLLOW} are missing on some platforms.
 @end itemize
diff --git a/lib/faccessat.c b/lib/faccessat.c
new file mode 100644 (file)
index 0000000..a449b02
--- /dev/null
@@ -0,0 +1,49 @@
+/* Check the access rights of a file relative to an open directory.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+
+   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 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, see <http://www.gnu.org/licenses/>.  */
+
+/* written by Eric Blake */
+
+#include <config.h>
+
+#include <unistd.h>
+
+#include "dirname.h" /* solely for definition of IS_ABSOLUTE_FILE_NAME */
+#include "openat.h"
+#include "openat-priv.h"
+#include "save-cwd.h"
+
+#ifndef HAVE_ACCESS
+/* Mingw lacks access, but it also lacks real vs. effective ids, so
+   the gnulib euidaccess module is good enough.  */
+# undef access
+# define access euidaccess
+#endif
+
+/* Invoke access or euidaccess on file, FILE, using mode MODE, in the directory
+   open on descriptor FD.  If possible, do it without changing the
+   working directory.  Otherwise, resort to using save_cwd/fchdir,
+   then mkdir/restore_cwd.  If either the save_cwd or the restore_cwd
+   fails, then give a diagnostic and exit nonzero.
+   Note that this implementation only supports AT_EACCESS, although some
+   native versions also support AT_SYMLINK_NOFOLLOW.  */
+
+#define AT_FUNC_NAME faccessat
+#define AT_FUNC_F1 euidaccess
+#define AT_FUNC_F2 access
+#define AT_FUNC_USE_F1_COND AT_EACCESS
+#define AT_FUNC_POST_FILE_PARAM_DECLS , int mode, int flag
+#define AT_FUNC_POST_FILE_ARGS        , mode
+#include "at-func.c"
index 6c88b47..cadb6a1 100644 (file)
@@ -192,6 +192,15 @@ int openat (int fd, char const *file, int flags, /* mode_t mode */ ...);
 # define AT_REMOVEDIR 1
 #endif
 
+/* Solaris 9 lacks these two, so just pick unique values.  */
+#ifndef AT_SYMLINK_FOLLOW
+# define AT_SYMLINK_FOLLOW 2
+#endif
+
+#ifndef AT_EACCESS
+# define AT_EACCESS 4
+#endif
+
 
 #endif /* _GL_FCNTL_H */
 #endif /* _GL_FCNTL_H */
index e6db70b..d635e79 100644 (file)
 # define STDERR_FILENO 2
 #endif
 
+/* Ensure *_OK functions exist.  */
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+
 /* Declare overridden functions.  */
 
 #ifdef __cplusplus
@@ -163,6 +172,19 @@ int unlinkat (int fd, char const *file, int flag);
 #endif /* @GNULIB_OPENAT@ */
 
 
+#if @GNULIB_FACCESSAT@
+# if !@HAVE_FACCESSAT@
+int faccessat (int fd, char const *file, int mode, int flag);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef faccessat
+# define faccessat(d,n,m,f)                        \
+    (GL_LINK_WARNING ("faccessat is not portable - " \
+                      "use gnulib module faccessat for portability"), \
+     fchownat (d, n, m, f))
+#endif
+
+
 #if @GNULIB_CLOSE@
 # if @REPLACE_CLOSE@
 /* Automatically included by modules that need a replacement for close.  */
diff --git a/m4/faccessat.m4 b/m4/faccessat.m4
new file mode 100644 (file)
index 0000000..f21dc13
--- /dev/null
@@ -0,0 +1,21 @@
+# serial 1
+# See if we need to provide faccessat replacement.
+
+dnl Copyright (C) 2009 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Written by Eric Blake.
+
+AC_DEFUN([gl_FUNC_FACCESSAT],
+[
+  AC_REQUIRE([gl_FUNC_OPENAT])
+  AC_REQUIRE([gl_FUNC_EUIDACCESS])
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_CHECK_FUNCS_ONCE([access])
+  AC_CHECK_FUNCS_ONCE([faccessat])
+  if test $ac_cv_func_faccessat = no; then
+    HAVE_FACCESSAT=0
+  fi
+])
index c8e93da..928f5bc 100644 (file)
@@ -39,6 +39,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   GNULIB_DUP3=0;             AC_SUBST([GNULIB_DUP3])
   GNULIB_ENVIRON=0;          AC_SUBST([GNULIB_ENVIRON])
   GNULIB_EUIDACCESS=0;       AC_SUBST([GNULIB_EUIDACCESS])
+  GNULIB_FACCESSAT=0;        AC_SUBST([GNULIB_FACCESSAT])
   GNULIB_FCHDIR=0;           AC_SUBST([GNULIB_FCHDIR])
   GNULIB_FSYNC=0;            AC_SUBST([GNULIB_FSYNC])
   GNULIB_FTRUNCATE=0;        AC_SUBST([GNULIB_FTRUNCATE])
@@ -62,6 +63,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS],
   HAVE_DUP2=1;            AC_SUBST([HAVE_DUP2])
   HAVE_DUP3=1;            AC_SUBST([HAVE_DUP3])
   HAVE_EUIDACCESS=1;      AC_SUBST([HAVE_EUIDACCESS])
+  HAVE_FACCESSAT=1;       AC_SUBST([HAVE_FACCESSAT])
   HAVE_FSYNC=1;           AC_SUBST([HAVE_FSYNC])
   HAVE_FTRUNCATE=1;       AC_SUBST([HAVE_FTRUNCATE])
   HAVE_GETDOMAINNAME=1;   AC_SUBST([HAVE_GETDOMAINNAME])
diff --git a/modules/faccessat b/modules/faccessat
new file mode 100644 (file)
index 0000000..d7737ba
--- /dev/null
@@ -0,0 +1,32 @@
+Description:
+faccessat() function: check user's permissions for a file.
+
+Files:
+lib/faccessat.c
+m4/faccessat.m4
+
+Depends-on:
+euidaccess
+extensions
+fcntl-h
+openat
+unistd
+
+configure.ac:
+gl_FUNC_FACCESSAT
+gl_UNISTD_MODULE_INDICATOR([faccessat])
+
+Makefile.am:
+
+Include:
+<fcntl.h>
+<unistd.h>
+
+Link:
+$(LIB_EACCESS)
+
+License:
+GPL
+
+Maintainer:
+Jim Meyering, Eric Blake
index 4c5add7..b48b4b9 100644 (file)
@@ -32,6 +32,7 @@ unistd.h: unistd.in.h
              -e 's|@''GNULIB_DUP3''@|$(GNULIB_DUP3)|g' \
              -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \
              -e 's|@''GNULIB_EUIDACCESS''@|$(GNULIB_EUIDACCESS)|g' \
+             -e 's|@''GNULIB_FACCESSAT''@|$(GNULIB_FACCESSAT)|g' \
              -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \
              -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \
              -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \
@@ -55,6 +56,7 @@ unistd.h: unistd.in.h
              -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \
              -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \
              -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \
+             -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \
              -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \
              -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \
              -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \