From 973333dc422903c68f8a34c9612ef583ed0cb6ff Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 3 Sep 2009 13:41:18 -0600 Subject: [PATCH] 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. Signed-off-by: Eric Blake --- ChangeLog | 13 ++++++++++ MODULES.html.sh | 1 + doc/posix-functions/faccessat.texi | 14 +++++++---- doc/posix-headers/fcntl.texi | 6 ++--- lib/faccessat.c | 49 ++++++++++++++++++++++++++++++++++++++ lib/fcntl.in.h | 9 +++++++ lib/unistd.in.h | 22 +++++++++++++++++ m4/faccessat.m4 | 21 ++++++++++++++++ m4/unistd_h.m4 | 2 ++ modules/faccessat | 32 +++++++++++++++++++++++++ modules/unistd | 2 ++ 11 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 lib/faccessat.c create mode 100644 m4/faccessat.m4 create mode 100644 modules/faccessat diff --git a/ChangeLog b/ChangeLog index 4358759ba..02e06bde6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2009-09-03 Eric Blake + 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. diff --git a/MODULES.html.sh b/MODULES.html.sh index bcecc5546..b60ef61e4 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -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 diff --git a/doc/posix-functions/faccessat.texi b/doc/posix-functions/faccessat.texi index bf3335d67..835a5d8db 100644 --- a/doc/posix-functions/faccessat.texi +++ b/doc/posix-functions/faccessat.texi @@ -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 diff --git a/doc/posix-headers/fcntl.texi b/doc/posix-headers/fcntl.texi index 020586c4c..5cf86ee97 100644 --- a/doc/posix-headers/fcntl.texi +++ b/doc/posix-headers/fcntl.texi @@ -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 index 000000000..a449b0217 --- /dev/null +++ b/lib/faccessat.c @@ -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 . */ + +/* written by Eric Blake */ + +#include + +#include + +#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" diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index 6c88b476f..cadb6a157 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -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 */ diff --git a/lib/unistd.in.h b/lib/unistd.in.h index e6db70ba5..d635e7956 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -106,6 +106,15 @@ # 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 index 000000000..f21dc13ee --- /dev/null +++ b/m4/faccessat.m4 @@ -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 +]) diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index c8e93da19..928f5bcb0 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -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 index 000000000..d7737bac9 --- /dev/null +++ b/modules/faccessat @@ -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: + + + +Link: +$(LIB_EACCESS) + +License: +GPL + +Maintainer: +Jim Meyering, Eric Blake diff --git a/modules/unistd b/modules/unistd index 4c5add7db..b48b4b954 100644 --- a/modules/unistd +++ b/modules/unistd @@ -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' \ -- 2.11.0