changeset 17148:8e5a994a5d5b

fcntl-h: default O_SEARCH, O_EXEC to O_PATH if available Linux kernel 2.6.39 introduced O_PATH (see <http://lwn.net/Articles/433854/>) and this is a better fallback for O_SEARCH and O_EXEC than O_RDONLY, if O_PATH is available. * doc/posix-headers/fcntl.texi (fcntl.h): Document this. * lib/fcntl.in.h (O_EXEC, O_SEARCH) [O_PATH]: Default to O_PATH. * lib/fcntl.in.h (O_ACCMODE): * tests/test-fcntl-h.c (main): Do not reject O_ACCMODE merely because it has more than the minimal number of bits, as POSIX allows extensions here.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 05 Nov 2012 13:53:36 -0800
parents c4a6dcd5073a
children a49df7b88261
files ChangeLog doc/posix-headers/fcntl.texi lib/fcntl.in.h tests/test-fcntl-h.c
diffstat 4 files changed, 28 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2012-11-05  Paul Eggert  <eggert@cs.ucla.edu>
+
+	fcntl-h: default O_SEARCH, O_EXEC to O_PATH if available
+	Linux kernel 2.6.39 introduced O_PATH (see
+	<http://lwn.net/Articles/433854/>) and this is a better fallback
+	for O_SEARCH and O_EXEC than O_RDONLY, if O_PATH is available.
+	* doc/posix-headers/fcntl.texi (fcntl.h): Document this.
+	* lib/fcntl.in.h (O_EXEC, O_SEARCH) [O_PATH]: Default to O_PATH.
+	* lib/fcntl.in.h (O_ACCMODE):
+	* tests/test-fcntl-h.c (main):
+	Do not reject O_ACCMODE merely because it has more than the
+	minimal number of bits, as POSIX allows extensions here.
+
 2012-11-04  Andrew Warshall  <warshall@99main.com>  (tiny change)
 
 	mountlist: do not classify a bind-mounted dir entry as "dummy"
--- a/doc/posix-headers/fcntl.texi
+++ b/doc/posix-headers/fcntl.texi
@@ -28,7 +28,9 @@
 
 @item
 @samp{O_EXEC} and @samp{O_SEARCH} are not defined on some platforms.
-Gnulib defines these macros to @samp{O_RDONLY}, which is typically 0.
+On platforms such as GNU/Linux 2.6.39 and later that have @samp{O_PATH},
+Gnulib defines these macros to @samp{O_PATH}.
+On other platforms, it defines them to @samp{O_RDONLY}, which is typically 0.
 
 @item
 @samp{O_ACCMODE} is not defined on some platforms:
--- a/lib/fcntl.in.h
+++ b/lib/fcntl.in.h
@@ -213,7 +213,11 @@
 #endif
 
 #ifndef O_EXEC
-# define O_EXEC O_RDONLY /* This is often close enough in older systems.  */
+# ifdef O_PATH
+#  define O_EXEC O_PATH
+# else
+#  define O_EXEC O_RDONLY /* This is often close enough in older systems.  */
+# endif
 #endif
 
 #ifndef O_IGNORE_CTTY
@@ -270,7 +274,11 @@
 #endif
 
 #ifndef O_SEARCH
-# define O_SEARCH O_RDONLY /* This is often close enough in older systems.  */
+# ifdef O_PATH
+#  define O_SEARCH O_PATH
+# else
+#  define O_SEARCH O_RDONLY /* This is often close enough in older systems.  */
+# endif
 #endif
 
 #ifndef O_SYNC
@@ -281,7 +289,7 @@
 # define O_TTY_INIT 0
 #endif
 
-#if O_ACCMODE != (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
+#if ~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
 # undef O_ACCMODE
 # define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
 #endif
--- a/tests/test-fcntl-h.c
+++ b/tests/test-fcntl-h.c
@@ -61,7 +61,7 @@
 #if O_SEARCH && O_EXEC != O_SEARCH && O_SEARCH != O_RDONLY
     case O_SEARCH:
 #endif
-      i = O_ACCMODE == (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH);
+      i = ! (~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH));
       break;
 
       /* Everyone should have these */