From murdoch.duncan at gmail.com  Mon Sep 26 23:46:19 2016
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Mon, 26 Sep 2016 17:46:19 -0400
Subject: [Rd] Recursive dir.create() on Windows shares
In-Reply-To: <CABKQe-ZbusW48e0=YFbR562DXFqPaDX7bb6FZFaQpBcF5Hy+pw@mail.gmail.com>
References: <CABKQe-ZbusW48e0=YFbR562DXFqPaDX7bb6FZFaQpBcF5Hy+pw@mail.gmail.com>
Message-ID: <95074f7b-8e21-7a98-0637-9973a31dc230@gmail.com>

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



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