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 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 eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org