[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