bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

directory file descriptor O_WRONLY sync from coreutils


From: Paul Eggert
Subject: directory file descriptor O_WRONLY sync from coreutils
Date: Mon, 09 Jan 2006 15:20:50 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

I installed this:

2006-01-09  Paul Eggert  <address@hidden>

        Sync from coreutils.

        * lib/chdir-long.c (cdb_free): Don't bother trying to open directory
        for write access: POSIX says that must fail.
        * lib/fts.c (diropen): Likewise.
        * lib/save-cwd.c (save_cwd): Likewise.
        * lib/chdir-long.c (cdb_free): Open with O_NOCTTY | O_NONBLOCK as
        well, for minor improvements on hosts that lack O_DIRECTORY.
        * lib/chown.c (rpl_chown) [CHOWN_MODIFIES_SYMLINK]:
        Don't try O_WRONLY unless O_RDONLY failed wth EACCES.
        Fall back on chown if open failed with EACCES.

Index: lib/chdir-long.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/chdir-long.c,v
retrieving revision 1.6
diff -p -u -r1.6 chdir-long.c
--- lib/chdir-long.c    19 Sep 2005 17:28:14 -0000      1.6
+++ lib/chdir-long.c    9 Jan 2006 23:02:07 -0000
@@ -77,13 +77,10 @@ cdb_free (struct cd_buf const *cdb)
 static int
 cdb_advance_fd (struct cd_buf *cdb, char const *dir)
 {
-  int new_fd = openat (cdb->fd, dir, O_RDONLY | O_DIRECTORY);
+  int new_fd = openat (cdb->fd, dir,
+                      O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
   if (new_fd < 0)
-    {
-      new_fd = openat (cdb->fd, dir, O_WRONLY | O_DIRECTORY);
-      if (new_fd < 0)
-       return -1;
-    }
+    return -1;
 
   cdb_free (cdb);
   cdb->fd = new_fd;
Index: lib/chown.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/chown.c,v
retrieving revision 1.16
diff -p -u -r1.16 chown.c
--- lib/chown.c 23 Sep 2005 04:15:13 -0000      1.16
+++ lib/chown.c 9 Jan 2006 23:02:07 -0000
@@ -27,12 +27,15 @@
    most systems.  */
 #undef chown
 
+#include <stdbool.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 
+#include "stat-macros.h"
+
 /* Provide a more-closely POSIX-conforming version of chown on
    systems with one or both of the following problems:
    - chown doesn't treat an ID of -1 as meaning
@@ -66,20 +69,34 @@ rpl_chown (const char *file, uid_t uid, 
        on the symlink itself.  To work around that, we open the
        file (but this can fail due to lack of read or write permission) and
        use fchown on the resulting descriptor.  */
-    int fd = open (file, O_RDONLY | O_NONBLOCK | O_NOCTTY);
-    if (fd < 0
-       && (fd = open (file, O_WRONLY | O_NONBLOCK | O_NOCTTY)) < 0)
-      return -1;
-    if (fchown (fd, uid, gid))
+    int open_flags = O_NONBLOCK | O_NOCTTY;
+    int fd = open (file, O_RDONLY | open_flags);
+    if (0 <= fd
+       || (errno == EACCES
+           && 0 <= (fd = open (file, O_WRONLY | open_flags))))
       {
+       int result = fchown (fd, uid, gid);
        int saved_errno = errno;
+
+       /* POSIX says fchown can fail with errno == EINVAL on sockets,
+          so fall back on chown in that case.  */
+       struct stat sb;
+       bool fchown_socket_failure =
+         (result != 0 && saved_errno == EINVAL
+          && fstat (fd, &sb) == 0 && S_ISFIFO (sb.st_mode));
+
        close (fd);
-       errno = saved_errno;
-       return -1;
+
+       if (! fchown_socket_failure)
+         {
+           errno = saved_errno;
+           return result;
+         }
       }
-    return close (fd);
+    else if (errno != EACCES)
+      return -1;
   }
-#else
-  return chown (file, uid, gid);
 #endif
+
+  return chown (file, uid, gid);
 }
Index: lib/fts.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/fts.c,v
retrieving revision 1.7
diff -p -u -r1.7 fts.c
--- lib/fts.c   14 Aug 2005 14:45:16 -0000      1.7
+++ lib/fts.c   9 Jan 2006 23:02:07 -0000
@@ -1,6 +1,6 @@
 /* Traverse a file hierarchy.
 
-   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006 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
@@ -203,10 +203,7 @@ static int
 internal_function
 diropen (char const *dir)
 {
-  int fd = open (dir, O_RDONLY | O_DIRECTORY);
-  if (fd < 0)
-    fd = open (dir, O_WRONLY | O_DIRECTORY);
-  return fd;
+  return open (dir, O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK);
 }
 
 FTS *
@@ -244,7 +241,8 @@ fts_open (char * const *argv,
 #ifndef MAXPATHLEN
 # define MAXPATHLEN 1024
 #endif
-       if (! fts_palloc(sp, MAX(fts_maxarglen(argv), MAXPATHLEN)))
+       size_t maxarglen = fts_maxarglen(argv);
+       if (! fts_palloc(sp, MAX(maxarglen, MAXPATHLEN)))
                goto mem1;
 
        /* Allocate/initialize root's parent. */
Index: lib/save-cwd.c
===================================================================
RCS file: /cvsroot/gnulib/gnulib/lib/save-cwd.c,v
retrieving revision 1.25
diff -p -u -r1.25 save-cwd.c
--- lib/save-cwd.c      23 Sep 2005 04:15:13 -0000      1.25
+++ lib/save-cwd.c      9 Jan 2006 23:02:07 -0000
@@ -75,12 +75,8 @@ save_cwd (struct saved_cwd *cwd)
   cwd->desc = open (".", O_RDONLY);
   if (cwd->desc < 0)
     {
-      cwd->desc = open (".", O_WRONLY);
-      if (cwd->desc < 0)
-       {
-         cwd->name = xgetcwd ();
-         return cwd->name ? 0 : -1;
-       }
+      cwd->name = xgetcwd ();
+      return cwd->name ? 0 : -1;
     }
 
   return 0;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]