[R] Cannot use R on Windows when installed to an external drive with a space in the path

Ivan Krylov kry|ov@r00t @end|ng |rom gm@||@com
Mon Oct 22 19:15:30 CEST 2018


This is a bin\R.exe + bin\Rscript.exe bug.

On Windows, where the system call to create a process only takes one
command line string instead of an array of command line parameters[0]
(and the C runtimes usually call CommandLineToArgvW[1] behind the
scenes to get an array back), execv() does nothing to prepare a
properly-quoted command line and just concatenates its arguments[2].
Moreover, Windows version of execv() is effectively undocumented[3],
nor there is any information about the suggested replacement[4].
(You can call it a Windows bug instead.)

Short file names are not a guaranteed solution, because they may
not be available at all on some filesystems[5] (which is how this
error has been encountered). In the general case, "argument quoting
hell"[6] is unavoidable on Windows, but the code from [2] implements
the proper conversion from an array of strings to a single quoted
command line, ready to be parsed by the launched process.

char* getRHOME(int m) in src/gnuwin32/rhome.c tries to return a short
path (assuming it won't contain spaces). This is used by rcmdfn() from
src/gnuwin32/front-ends/rcmdfn.c to system() a command line built with
no quoting, causing the error. rcmdfn() is called from
src/gnuwin32/front-ends/R.c, which seems to contain the entry point for
R\R-3.3.3\bin\R.exe.

Fortunately, in src/unix/Rscript.c the whole mess seems to be avoided by
having it directly include rterm.c and then call AppMain() on Windows,
passing the command line parameter array. Same goes for
src/gnuwin32/front-ends/graphappmain.c. The corresponding executables
reside in the architecture-specific subdirectory of ...\bin\.

So if you run Rgui.exe, Rterm.exe or Rscript.exe from
R-3.3.3\bin\i386 instead of R-3.3.3\bin, no extra cmd.exe processes
should be spawned and the badly-formed system() should be avoided.

-- 
Best regards,
Ivan

[0]
https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createprocessa

That's probably for historical reasons, because Win32 API wanted to
stay mostly source-compatible with Win16 API, and Win16 API may have
evolved from DOS system calls, where the command line was, indeed, a
single string pointer.

[1]
https://docs.microsoft.com/en-us/windows/desktop/api/shellapi/nf-shellapi-commandlinetoargvw

[2]
https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/

[3]
https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2012/ms235416(v=vs.110)

[4]
https://docs.microsoft.com/en-us/cpp/c-runtime-library/exec-wexec-functions?view=vs-2017

[5] https://blogs.msdn.microsoft.com/oldnewthing/20181004-00/?p=99895

[6] quoted from Rscript.c




More information about the R-help mailing list