]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
remove.c: accommodate systems with negative errno values
authorJim Meyering <jim@meyering.net>
Mon, 24 Mar 2008 16:38:27 +0000 (17:38 +0100)
committerJim Meyering <meyering@redhat.com>
Sun, 6 Apr 2008 07:26:32 +0000 (09:26 +0200)
This is required at least on Haiku and BeOS.
* src/remove.c (write_protected_non_symlink): Return 1 for a write-
protected non-symlink, 0 if we determine it's not, and -1 upon
error (setting errno accordingly only in this final case).
(prompt): Deal with the changed semantics of the above function.
Based on this patch from Axel Dörfler:
http://thread.gmane.org/gmane.comp.gnu.coreutils.bugs/13071

THANKS
src/remove.c

diff --git a/THANKS b/THANKS
index 1f8566ac12fdcfc87f3541dc2a4980c01ad7978e..f08910eecf2480a24d9dcc294d9d2bd4a921dc16 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -21,6 +21,7 @@ Albert Hopkins                      ahopkins@dynacare.com
 Alberto Accomazzi                   alberto@cfa0.harvard.edu
 aldomel                             aldomel@ix.netcom.com
 Alen Muzinic                        zveki@fly.cc.fer.hr
+Axel Dörfler                        axeld@pinc-software.de
 Alexandre Duret-Lutz                duret_g@epita.fr
 Alexey Solovyov                     alekso@math.uu.se
 Alexey Vyskubov                     alexey@pippuri.mawhrin.net
index 7ba1e38eff9bdf5995a4ba32451d6e112f787d39..07c2f71ba596efbab1ae20150f9d2c02df3259ef 100644 (file)
@@ -728,9 +728,9 @@ AD_is_removable (Dirstack_state const *ds, char const *file)
   return ! (top->unremovable && hash_lookup (top->unremovable, file));
 }
 
-/* Return -1 if FILE is an unwritable non-symlink,
+/* Return 1 if FILE is an unwritable non-symlink,
    0 if it is writable or some other type of file,
-   a positive error number if there is some problem in determining the answer.
+   -1 and set errno if there is some problem in determining the answer.
    Set *BUF to the file status.
    This is to avoid calling euidaccess when FILE is a symlink.  */
 static int
@@ -742,7 +742,7 @@ write_protected_non_symlink (int fd_cwd,
   if (can_write_any_file ())
     return 0;
   if (cache_fstatat (fd_cwd, file, buf, AT_SYMLINK_NOFOLLOW) != 0)
-    return errno;
+    return -1;
   if (S_ISLNK (buf->st_mode))
     return 0;
   /* Here, we know FILE is not a symbolic link.  */
@@ -799,15 +799,18 @@ write_protected_non_symlink (int fd_cwd,
       = obstack_object_size (&ds->dir_stack) + strlen (file);
 
     if (MIN (PATH_MAX, 8192) <= file_name_len)
-      return euidaccess_stat (buf, W_OK) ? 0 : -1;
+      return ! euidaccess_stat (buf, W_OK);
     if (euidaccess (xfull_filename (ds, file), W_OK) == 0)
       return 0;
     if (errno == EACCES)
-      return -1;
+      {
+       errno = 0;
+       return 1;
+      }
 
     /* Perhaps some other process has removed the file, or perhaps this
        is a buggy NFS client.  */
-    return errno;
+    return -1;
   }
 }
 
@@ -839,14 +842,19 @@ prompt (int fd_cwd, Dirstack_state const *ds, char const *filename,
   if (x->interactive == RMI_NEVER)
     return RM_OK;
 
+  int wp_errno = 0;
+
   if (!x->ignore_missing_files
       && ((x->interactive == RMI_ALWAYS) || x->stdin_tty)
       && dirent_type != DT_LNK)
-    write_protected = write_protected_non_symlink (fd_cwd, filename, ds, sbuf);
+    {
+      write_protected = write_protected_non_symlink (fd_cwd, filename, ds, sbuf);
+      wp_errno = errno;
+    }
 
   if (write_protected || x->interactive == RMI_ALWAYS)
     {
-      if (write_protected <= 0 && dirent_type == DT_UNKNOWN)
+      if (0 <= write_protected && dirent_type == DT_UNKNOWN)
        {
          if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) == 0)
            {
@@ -860,11 +868,12 @@ prompt (int fd_cwd, Dirstack_state const *ds, char const *filename,
          else
            {
              /* This happens, e.g., with `rm '''.  */
-             write_protected = errno;
+             write_protected = -1;
+             wp_errno = errno;
            }
        }
 
-      if (write_protected <= 0)
+      if (0 <= write_protected)
        switch (dirent_type)
          {
          case DT_LNK:
@@ -875,15 +884,18 @@ prompt (int fd_cwd, Dirstack_state const *ds, char const *filename,
 
          case DT_DIR:
            if (!x->recursive)
-             write_protected = EISDIR;
+             {
+               write_protected = -1;
+               wp_errno = EISDIR;
+             }
            break;
          }
 
       char const *quoted_name = quote (full_filename (filename));
 
-      if (0 < write_protected)
+      if (write_protected < 0)
        {
-         error (0, write_protected, _("cannot remove %s"), quoted_name);
+         error (0, wp_errno, _("cannot remove %s"), quoted_name);
          return RM_ERROR;
        }