[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#7823: Rm -f fails on non-existant file
From: |
Eric Blake |
Subject: |
bug#7823: Rm -f fails on non-existant file |
Date: |
Tue, 11 Jan 2011 07:56:31 -0700 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Lightning/1.0b3pre Mnenhy/0.8.3 Thunderbird/3.1.7 |
On 01/11/2011 05:58 AM, Nadav Har'El wrote:
> Unfortunately, I found a rare case where this is not happening.
>
> It appears that when mounting a Windows filesystem using Samba, if I try
> running:
> command
>
> #!/bin/sh
> mkdir emptydir
> rm -f emptydir/*
>
> The shell leaves this "*" unchanged, and rm gives this name to unlink(2),
> which oddly enough returns EINVAL (invalid argument) instead of the expected
> ENOENT (no such file or directory!).
Thanks for tracking this down.
>
> I'm guessing the smbfs people chose to give this as a special error when
> "invalid" characters are used in the file name (this is a concept that doesn't
> exist in Unix), but I'm not sure why it was so important to them to not
> just return ENOENT in this case... But still, I think "rm" should behave
> well in this case.
Feel free to file a bug report to the smbfs people. POSIX does not
specify EINVAL (except for bad flags to unlinkat), but does have a
global clause that states that any errno not specifically listed may be
returned if it is a better fit than any mandated error. On the other
hand, the next version of POSIX will be mandating that the case of an
unsupported byte in a filename ('*' in the case of smbfs) shall fail
with EILSEQ, not EINVAL (that is, if they don't return the equally valid
ENOENT failure). See http://austingroupbugs.net/view.php?id=293, for
justification why smbfs ought to change their errno value away from EINVAL.
> Anyway, in remove.c, you have
>
> static inline bool
> nonexistent_file_errno (int errnum)
> {
> switch (errnum)
> {
> case ENOENT:
> case ENOTDIR:
> return true;
> default:
> return false;
> }
> }
>
> And I wonder whether EINVAL shouldn't also be added to it.
Yes, since POSIX doesn't specify EINVAL for any other situation, I see
no harm in globally exempting it (with a comment why) in our source
code; likewise, I see no problem in also adding EILSEQ to that list,
whether or not smbfs also fixes their bug.
Is it okay if I push this patch in your name?
From 3201907296fd18084b68f062709d589c18e3ffe6 Mon Sep 17 00:00:00 2001
From: Nadav Har'El <nyh AT math.technion.ac.il>
Date: Tue, 11 Jan 2011 07:53:07 -0700
Subject: [PATCH] rm: ignore errno related to invalid file names
* src/remove.c (nonexistent_file_errno): Also skip EINVAL and
EILSEQ, for at least smbfs rejection of '*' in file names.
---
src/remove.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/src/remove.c b/src/remove.c
index f7b00c6..3814232 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -378,10 +378,18 @@ nonexistent_file_errno (int errnum)
exist, but be (in)accessible only via too long a symlink chain.
Likewise for ENAMETOOLONG, since rm -f ./././.../foo may fail
if the "..." part expands to a long enough sequence of "./"s,
- even though ./foo does indeed exist. */
+ even though ./foo does indeed exist.
+
+ Another case to consider is when a particular name is invalid for
+ a given file system. In 2011, smbfs returns EINVAL, but the next
+ revision of POSIX will require EILSEQ for that situation:
+ http://austingroupbugs.net/view.php?id=293
+ */
switch (errnum)
{
+ case EILSEQ:
+ case EINVAL:
case ENOENT:
case ENOTDIR:
return true;
--
1.7.3.4
--
Eric Blake address@hidden +1-801-349-2682
Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature