[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
From: |
Paul Eggert |
Subject: |
[PATCH] fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable |
Date: |
Wed, 01 Sep 2010 13:49:45 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.11) Gecko/20100713 Thunderbird/3.0.6 |
POSIX 2008 specifies a new 'open' flag O_SEARCH, which can be used
when one needs search access to a directory but not read access.
On systems where it is available, it works in some cases where
O_RDONLY does not, namely on directories that are searchable but
not readable, and which need only to be searchable. If O_SEARCH
is not available, fall back to the traditional method of using
O_RDONLY.
* lib/fcntl.in.h (O_SEARCH): #define to O_RDONLY if not defined.
* lib/chdir-long.c (cdb_advance_fd): Use O_SEARCH, not O_RDONLY,
when opening a directory that needs only to be searchable.
* lib/chdir-safer.c (chdir_no_follow): Likewise.
* lib/fts.c (diropen, fts_open, fd_ring_check): Likewise.
* lib/openat-proc.c (openat_proc_name): Likewise.
* lib/openat.c (openat_needs_fchdir): Likewise.
* lib/save-cwd.c (save_cwd): Likewise.
* lib/savewd.c (savewd_save, savewd_chdir): Likewise.
---
ChangeLog | 22 ++++++++++++++++++++++
lib/chdir-long.c | 2 +-
lib/chdir-safer.c | 11 +++++++----
lib/fcntl.in.h | 4 ++++
lib/fts.c | 6 +++---
lib/openat-proc.c | 2 +-
lib/openat.c | 2 +-
lib/save-cwd.c | 2 +-
lib/savewd.c | 4 ++--
9 files changed, 42 insertions(+), 13 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 35d2ce0..2d03ea7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2010-09-01 Paul Eggert <address@hidden>
+
+ fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable
+
+ POSIX 2008 specifies a new 'open' flag O_SEARCH, which can be used
+ when one needs search access to a directory but not read access.
+ On systems where it is available, it works in some cases where
+ O_RDONLY does not, namely on directories that are searchable but
+ not readable, and which need only to be searchable. If O_SEARCH
+ is not available, fall back to the traditional method of using
+ O_RDONLY.
+
+ * lib/fcntl.in.h (O_SEARCH): #define to O_RDONLY if not defined.
+ * lib/chdir-long.c (cdb_advance_fd): Use O_SEARCH, not O_RDONLY,
+ when opening a directory that needs only to be searchable.
+ * lib/chdir-safer.c (chdir_no_follow): Likewise.
+ * lib/fts.c (diropen, fts_open, fd_ring_check): Likewise.
+ * lib/openat-proc.c (openat_proc_name): Likewise.
+ * lib/openat.c (openat_needs_fchdir): Likewise.
+ * lib/save-cwd.c (save_cwd): Likewise.
+ * lib/savewd.c (savewd_save, savewd_chdir): Likewise.
+
2010-08-28 Bruno Haible <address@hidden>
New module 'host-cpu-c-abi'.
diff --git a/lib/chdir-long.c b/lib/chdir-long.c
index 28e2407..a88e27f 100644
--- a/lib/chdir-long.c
+++ b/lib/chdir-long.c
@@ -72,7 +72,7 @@ static int
cdb_advance_fd (struct cd_buf *cdb, char const *dir)
{
int new_fd = openat (cdb->fd, dir,
- O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
+ O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
if (new_fd < 0)
return -1;
diff --git a/lib/chdir-safer.c b/lib/chdir-safer.c
index b3266b5..61c71c6 100644
--- a/lib/chdir-safer.c
+++ b/lib/chdir-safer.c
@@ -34,16 +34,19 @@
#endif
/* Like chdir, but fail if DIR is a symbolic link to a directory (or
- similar funny business), or if DIR is not readable. This avoids a
- minor race condition between when a directory is created or statted
- and when the process chdirs into it. */
+ similar funny business). This avoids a minor race condition
+ between when a directory is created or statted and when the process
+ chdirs into it.
+
+ On older systems lacking full support for O_SEARCH, this function
+ can also fail if DIR is not readable. */
int
chdir_no_follow (char const *dir)
{
int result = 0;
int saved_errno;
int fd = open (dir,
- O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK);
+ O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NOFOLLOW | O_NONBLOCK);
if (fd < 0)
return -1;
diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h
index 8fb7852..42fb81b 100644
--- a/lib/fcntl.in.h
+++ b/lib/fcntl.in.h
@@ -210,6 +210,10 @@ _GL_WARN_ON_USE (openat, "openat is not portable - "
# define O_RSYNC 0
#endif
+#ifndef O_SEARCH
+# define O_SEARCH O_RDONLY /* This is often close enough in older systems. */
+#endif
+
#ifndef O_SYNC
# define O_SYNC 0
#endif
diff --git a/lib/fts.c b/lib/fts.c
index e4351f8..a308a8c 100644
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -347,7 +347,7 @@ static inline int
internal_function
diropen (FTS const *sp, char const *dir)
{
- int open_flags = (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
+ int open_flags = (O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
| (ISSET (FTS_PHYSICAL) ? O_NOFOLLOW : 0));
int fd = (ISSET (FTS_CWDFD)
@@ -405,7 +405,7 @@ fts_open (char * const *argv,
early, doing it here saves us the trouble of ensuring
later (where it'd be messier) that "." can in fact
be opened. If not, revert to FTS_NOCHDIR mode. */
- int fd = open (".", O_RDONLY);
+ int fd = open (".", O_SEARCH);
if (fd < 0)
{
/* Even if `.' is unreadable, don't revert to FTS_NOCHDIR mode
@@ -1646,7 +1646,7 @@ fd_ring_check (FTS const *sp)
int fd = i_ring_pop (&fd_w);
if (0 <= fd)
{
- int parent_fd = openat (cwd_fd, "..", O_RDONLY);
+ int parent_fd = openat (cwd_fd, "..", O_SEARCH);
if (parent_fd < 0)
{
// Warn?
diff --git a/lib/openat-proc.c b/lib/openat-proc.c
index 2538412..76fe42c 100644
--- a/lib/openat-proc.c
+++ b/lib/openat-proc.c
@@ -75,7 +75,7 @@ openat_proc_name (char buf[OPENAT_BUFFER_SIZE], int fd, char
const *file)
problem is exhibited on code that built on Solaris 8 and
running on Solaris 10. */
- int proc_self_fd = open ("/proc/self/fd", O_RDONLY);
+ int proc_self_fd = open ("/proc/self/fd", O_SEARCH);
if (proc_self_fd < 0)
proc_status = -1;
else
diff --git a/lib/openat.c b/lib/openat.c
index f2eac86..9970e46 100644
--- a/lib/openat.c
+++ b/lib/openat.c
@@ -244,7 +244,7 @@ bool
openat_needs_fchdir (void)
{
bool needs_fchdir = true;
- int fd = open ("/", O_RDONLY);
+ int fd = open ("/", O_SEARCH);
if (0 <= fd)
{
diff --git a/lib/save-cwd.c b/lib/save-cwd.c
index cf43a35..8e636c2 100644
--- a/lib/save-cwd.c
+++ b/lib/save-cwd.c
@@ -76,7 +76,7 @@ save_cwd (struct saved_cwd *cwd)
{
cwd->name = NULL;
- cwd->desc = open (".", O_RDONLY);
+ cwd->desc = open (".", O_SEARCH);
if (!GNULIB_FCNTL_SAFER)
cwd->desc = fd_safer (cwd->desc);
if (cwd->desc < 0)
diff --git a/lib/savewd.c b/lib/savewd.c
index e111207..9ec9877 100644
--- a/lib/savewd.c
+++ b/lib/savewd.c
@@ -45,7 +45,7 @@ savewd_save (struct savewd *wd)
case INITIAL_STATE:
/* Save the working directory, or prepare to fall back if possible. */
{
- int fd = open_safer (".", O_RDONLY);
+ int fd = open_safer (".", O_SEARCH);
if (0 <= fd)
{
wd->state = FD_STATE;
@@ -105,7 +105,7 @@ savewd_chdir (struct savewd *wd, char const *dir, int
options,
|| (options & (HAVE_WORKING_O_NOFOLLOW ? SAVEWD_CHDIR_NOFOLLOW : 0)))
{
fd = open (dir,
- (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
+ (O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
| (options & SAVEWD_CHDIR_NOFOLLOW ? O_NOFOLLOW : 0)));
if (open_result)
--
1.7.2
- [PATCH] fcntl-h, etc.: prefer O_SEARCH to O_RDONLY when applicable,
Paul Eggert <=