[Rd] Recursive dir.create() on Windows shares

Evan Cortens ecortens at mtroyal.ca
Tue Sep 27 17:53:23 CEST 2016


One more comment on this. In Python, there is a function,
os.path.splitdrive(), that performs path splitting in the same way my patch
does. Here's a quote from the Python docs:

"If the path contains a UNC path, drive will contain the host name and
share, up to but not including the fourth separator. e.g.
splitdrive("//host/computer/dir") returns ("//host/computer", "/dir")" (see
https://docs.python.org/3/library/os.path.html#os.path.splitdrive )

The now-deprecated (as of Python 3.1) os.path.splitunc() treated UNC paths
in a similar way.

So this to say I believe the correct behaviour is to skip the first two
parts of a path beginning with \\ before attempting to create a directory
in a call to dir.create() with recursive = TRUE.

On Mon, Sep 26, 2016 at 3:46 PM, Duncan Murdoch <murdoch.duncan at gmail.com>
wrote:

> On 26/09/2016 5:27 PM, Evan Cortens wrote:
>
>> Hi folks,
>>
>> I've noticed that there's an issue with the recursive creation of
>> directories that reside on network shares. For example:
>>
>>
>>> dir.create('\\\\SERVERNAME\\Empl\\Home1\\active\\e\\ecortens
>> \\thisisatest',
>> recursive = TRUE)
>> Warning message:
>> In
>> dir.create("\\\\SERVERNAME\\Empl\\Home1\\active\\e\\ecortens
>> \\thisisatest",
>>  :
>>   cannot create dir '\\SERVERNAME\Empl', reason 'Permission denied'
>>
>> The issue is that dir.create() is skipping the server name, but it's not
>> skipping the share name. So, in the above example, it's trying to create
>> "Empl", which fails, setting errno to the code for "Permission denied",
>> instead of EEXIST, the code for "file already exists", because it's not
>> actually a file, and therefore can't exist as one. (Incidentally, the same
>> challenge arises with the system call _wstat(), which also will return a
>> -1, telling you that the share name doesn't exist.)
>>
>> The solution to this issue, then, is to skip not only the server name, but
>> the share name as well, which is easily done with one more line of code:
>>
>> C:\Users\ecortens\Software\R-devel\src>svn diff
>> Index: main/platform.c
>> ===================================================================
>> --- main/platform.c     (revision 71366)
>> +++ main/platform.c     (working copy)
>> @@ -2159,10 +2159,11 @@
>>      while (*p == L'\\' && wcslen(dir) > 1 && *(p-1) != L':') *p-- =
>> L'\0';
>>      if (recursive) {
>>         p = dir;
>> -       /* skip leading \\share */
>> +       /* skip leading \\server\share */
>>         if (*p == L'\\' && *(p+1) == L'\\') {
>>             p += 2;
>>             p = wcschr(p, L'\\');
>> +           p = wcschr(p+1, L'\\');
>>         }
>>         while ((p = wcschr(p+1, L'\\'))) {
>>             *p = L'\0';
>>
>> This fixes the issue for me, and I can create directories no problem.
>> However, I'm a little worried, as the code in platform.c has been this way
>> since 2008--surely this can't have been a bug since then. Yet I can't find
>> any indication that the UNC naming convention has changed, and I can't
>> find
>> any way that will let you test the pathname to see if it's
>> "\\server\share"
>> or "\\share".
>>
>> I've also filed this on bugzilla, and have updated it there.  See
>> https://bugs.r-project.org/bugzilla/show_bug.cgi?id=1715
>>
>> Thanks for an amazing piece of software!
>>
>> Best,
>>
>> Evan
>>
>> P. S. I'm new to the mailing list, so I apologize in advance if I'm
>> violating any conventions I'm unaware of.
>>
>>
> Presumably someone from Microsoft will respond to this.
>
> Duncan Murdoch
>
>


-- 
Evan Cortens, PhD
Institutional Analyst - Office of Institutional Analysis
Mount Royal University
403-440-6529

	[[alternative HTML version deleted]]



More information about the R-devel mailing list