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. -- Evan Cortens, PhD Institutional Analyst - Office of Institutional Analysis Mount Royal University 403-440-6529 [[alternative HTML version deleted]]
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
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]]