Hi,

the enclosed patch changes the following (remove.c against HEAD):

* write_protected_non_symlink() now returns -1 for error (errno will be
set accordingly), 0 for everything fine, and 1 if it's a write
protected file.
* prompt() now deals with the changed semantics of the above function.

It's needed because error codes are expressed with negative values on
some platforms like Haiku, and BeOS; previously, the code incorrectly
assumed error codes would always be positive.

Kind Regards,
   Axel Dörfler.

diff --git a/src/remove.c b/src/remove.c
index 9c6dc9e..61bc935 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -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,
-   0 if it is writable or some other type of file,
-   a positive error number if there is some problem in determining the answer.
+/* Return 1 if FILE is an unwritable non-symlink, 0 if it is writable or some
+   other type of file.
+   Returns -1 and sets 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);
+      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,15 +842,18 @@ prompt (int fd_cwd, Dirstack_state const *ds, char const 
*filename,
   if (x->interactive == RMI_NEVER)
     return RM_OK;
 
+  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);
 
-  if (write_protected || x->interactive == RMI_ALWAYS)
+  if (write_protected || errno || x->interactive == RMI_ALWAYS)
     {
-      if (write_protected <= 0 && dirent_type == DT_UNKNOWN)
+      if (errno == 0 && dirent_type == DT_UNKNOWN)
        {
+         /* Might fail, e.g., for `rm '''.  */
          if (cache_fstatat (fd_cwd, filename, sbuf, AT_SYMLINK_NOFOLLOW) == 0)
            {
              if (S_ISLNK (sbuf->st_mode))
@@ -857,14 +863,9 @@ prompt (int fd_cwd, Dirstack_state const *ds, char const 
*filename,
              /* Otherwise it doesn't matter, so leave it DT_UNKNOWN.  */
              *pdirent_type = dirent_type;
            }
-         else
-           {
-             /* This happens, e.g., with `rm '''.  */
-             write_protected = errno;
-           }
        }
 
-      if (write_protected <= 0)
+      if (errno == 0)
        switch (dirent_type)
          {
          case DT_LNK:
@@ -875,15 +876,15 @@ prompt (int fd_cwd, Dirstack_state const *ds, char const 
*filename,
 
          case DT_DIR:
            if (!x->recursive)
-             write_protected = EISDIR;
+             errno = EISDIR;
            break;
          }
 
       char const *quoted_name = quote (full_filename (filename));
 
-      if (0 < write_protected)
+      if (errno != 0)
        {
-         error (0, write_protected, _("cannot remove %s"), quoted_name);
+         error (0, errno, _("cannot remove %s"), quoted_name);
          return RM_ERROR;
        }
 
_______________________________________________
Bug-coreutils mailing list
Bug-coreutils@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to