On 9/24/2019 2:27 PM, Eric Blake wrote:
> On 9/24/19 12:55 PM, Ken Brown wrote:
>> If the last component of the directory name is a symlink followed by a
>> slash, rmdir should fail, even if the symlink resolves to an existing
>> empty directory.
>>
>> mkdir was similarly fixed in 2009 in commit
>> 52dba6a5c45e8d8ba1e237a15213311dc11d91fb.  Modify a comment to clarify
>> the purpose of that commit.
>>
>> Addresses https://cygwin.com/ml/cygwin/2019-09/msg00221.html.
>> ---
>>   winsup/cygwin/dir.cc | 27 +++++++++++++++++++++++----
>>   1 file changed, 23 insertions(+), 4 deletions(-)
>>
>> diff --git a/winsup/cygwin/dir.cc b/winsup/cygwin/dir.cc
>> index b757851d5..0e0535891 100644
>> --- a/winsup/cygwin/dir.cc
>> +++ b/winsup/cygwin/dir.cc
>> @@ -305,15 +305,14 @@ mkdir (const char *dir, mode_t mode)
>>   
>>     __try
>>       {
>> -      /* POSIX says mkdir("symlink-to-missing/") should create the
>> -     directory "missing", but Linux rejects it with EEXIST.  Copy
>> -     Linux behavior for now.  */
>> -
>>         if (!*dir)
>>      {
>>        set_errno (ENOENT);
>>        __leave;
>>      }
>> +      /* Following Linux, do not resolve the last component of DIR if
>> +     it is a symlink, even if DIR has a trailing slash.  Achieve
>> +     this by stripping trailing slashes or backslashes.  */
> 
> Maybe even "Following Linux, and intentionally ignoring POSIX, do not..."
> 
>> +
>> +      /* Following Linux, do not resolve the last component of DIR if
>> +     it is a symlink, even if DIR has a trailing slash.  Achieve
>> +     this by stripping trailing slashes or backslashes.  */
>> +      if (isdirsep (dir[strlen (dir) - 1]))
>> +    {
>> +      /* This converts // to /, but since both give ENOTEMPTY,
>> +         we're okay.  */
>> +      char *buf;
>> +      char *p = stpcpy (buf = tp.c_get (), dir) - 1;
>> +      dir = buf;
>> +      while (p > dir && isdirsep (*p))
>> +        *p-- = '\0';
>> +    }
>>         if (!(fh = build_fh_name (dir, PC_SYM_NOFOLLOW)))
>>      __leave;   /* errno already set */;
>>   
> 
> Looks okay to me.

Thanks.  Does the "intentionally ignoring POSIX" part apply to rmdir also?  I 
didn't find it easy to decipher POSIX.

Even for mkdir, POSIX says, "If path names a symbolic link, mkdir() shall fail 
and set errno to [EEXIST]."  See 
https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html#tag_16_325.

But I'm not clear on how POSIX decides whether "path names a symbolic link" in 
the case where the last component is a symlink followed by a slash.

Ken

Reply via email to