[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