From e99cec677e1bf25595c6b65992c0228160508f8b Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 5 Nov 2012 13:53:36 -0800 Subject: [PATCH] fcntl-h: default O_SEARCH, O_EXEC to O_PATH if available Linux kernel 2.6.39 introduced O_PATH (see ) 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. --- ChangeLog | 13 +++++++++++++ doc/posix-headers/fcntl.texi | 4 +++- lib/fcntl.in.h | 14 +++++++++++--- tests/test-fcntl-h.c | 2 +- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2173fb262..3576e7a2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2012-11-05 Paul Eggert + + fcntl-h: default O_SEARCH, O_EXEC to O_PATH if available + Linux kernel 2.6.39 introduced O_PATH (see + ) 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 (tiny change) mountlist: do not classify a bind-mounted dir entry as "dummy" diff --git a/doc/posix-headers/fcntl.texi b/doc/posix-headers/fcntl.texi index eaa885da1..4a75a5462 100644 --- a/doc/posix-headers/fcntl.texi +++ b/doc/posix-headers/fcntl.texi @@ -28,7 +28,9 @@ non-zero value; otherwise, the gnulib replacement is 0. @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: diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index 5fdac2313..fb402ee1f 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -213,7 +213,11 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " #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 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " #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 @@ _GL_WARN_ON_USE (openat, "openat is not portable - " # 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 diff --git a/tests/test-fcntl-h.c b/tests/test-fcntl-h.c index 9515f828e..a6c962106 100644 --- a/tests/test-fcntl-h.c +++ b/tests/test-fcntl-h.c @@ -61,7 +61,7 @@ main (void) #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 */ -- 2.11.0