Subject: Re: bug#41001: mkdir: cannot create directory ‘test’: File exists

From: Jonny Grant <[email-masked]>
Date: Fri, 1 May 2020 17:16:13 +0100

On 01/05/2020 16:54, Eric Blake wrote:
> tag 41001 notabug
> thanks
> 
> On 5/1/20 10:06 AM, Jonny Grant wrote:
>> Hello!
>>
>> Can this error message be clarified? The directory already exists, it 
>> is not a file.
> 
> By one definition, a directory _is_ a file, just with different 
> semantics (in the same way a block device, character device, symlink, 
> fifo, or socket can also be a file).  It is not a regular file, but "a 
> file" is any entry stored in a directory, and as subdirectories are 
> stored in a directory, they count as files.
> 
>>
>> lib/mkdir-p.c:200 contains this line of code that triggers below:-
>>
>> error (0, mkdir_errno, _("cannot create directory %s"), quote (dir));
> 
> The error message in question is coming from libc's strerror() function; 
> if you want a different error message for EEXIST, you'll have to 
> convince glibc to update their error string tables.  It is not something 
> that coreutils directly controls.  And while we could indeed output a 
> custom message instead of using strerror(), that would confuse people 
> who have grown used to the strerror() message.
> 
>>
>> As it's easy enough to know that the reason mkdir fails is because 
>> 'test' a directory that already exists.
>>
>> Easy enough to check with stat() and S_ISDIR(sb.st_mode)
>>
>> Can this be changed? Maybe I can make a patch for it.
>> Jonny
>>
>>
>>
>> $ mkdir test
>> $ mkdir test
>> mkdir: cannot create directory ‘test’: File exists
> 
> If nothing else, you may want to consider using 'mkdir -p test', which 
> specifically checks if the reason for an EEXIST failure is because the 
> directory already exists.  Once you do that, you don't need to patch 
> coreutils.
> 
> Thus, I'm closing this as not a bug; but feel free to respond further 
> with any more comments on the topic.
> 

Hello Eric!

Yes, I can use mkdir -p as a workaround. Yes, I know everything is a 
file ultimately. However, most software does not call directories files 
as the routine behaviour for users.

'rm' and 'cat' are part of coreutils, that has output as I expected it.

$ rm test
rm: cannot remove 'test': Is a directory

$ cat test
cat: test: Is a directory

I'm certain glibc won't/can't change EEXIST, as it is POSIX.

$ strings test
strings: Warning: 'test' is a directory

$ vim test
"test" is a directory

on a tangent:
I see the cat output doesn't put the name in quotes, perhaps it should?

cat: 'test': Is a directory

Regards
Jonny