GitHub Viewer
/*
* SessionAsyncRProcess.cpp
*
* Copyright (C) 2009-19 by RStudio, PBC
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
#include
#include
#include
#include
#include
#include
#include
#include
namespace rstudio {
namespace session {
namespace async_r {
AsyncRProcess::AsyncRProcess():
isRunning_(false),
terminationRequested_(false)
{
}
void AsyncRProcess::start(const char* rCommand,
core::system::Options environment,
const core::FilePath& workingDir,
AsyncRProcessOptions rOptions,
std::vector rSourceFiles,
const std::string& input)
{
// file paths to be used for IPC (if any) requested by child process
ipcRequests_ = module_context::tempFile("rstudio-ipc-requests-", "rds");
ipcResponse_ = module_context::tempFile("rstudio-ipc-response-", "rds");
sharedSecret_ = core::system::generateUuid();
// R binary
core::FilePath rProgramPath;
core::Error error = module_context::rScriptPath(&rProgramPath);
if (error)
{
LOG_ERROR(error);
onCompleted(EXIT_FAILURE);
return;
}
// core R files for augmented async processes
if (rOptions & R_PROCESS_AUGMENTED)
{
// R files we wish to source to provide functionality to async process
const core::FilePath modulesPath =
session::options().modulesRSourcePath();
const core::FilePath rPath =
session::options().coreRSourcePath();
const core::FilePath rTools = rPath.completeChildPath("Tools.R");
// insert at begin as Tools.R needs to be sourced first
rSourceFiles.insert(rSourceFiles.begin(), rTools);
}
// args
std::vector args;
args.push_back("--slave");
if (rOptions & R_PROCESS_VANILLA)
args.push_back("--vanilla");
if (rOptions & R_PROCESS_NO_RDATA)
{
args.push_back("--no-save");
args.push_back("--no-restore");
}
// for windows we need to forward setInternet2
#ifdef _WIN32
if (!r::session::utils::isR3_3() && prefs::userPrefs().useInternet2())
args.push_back("--internet2");
#endif
args.push_back("-e");
bool needsQuote = false;
// On Windows, we turn the vector of strings into a single
// string to send over the command line, so we must ensure
// that the arguments following '-e' are quoted, so that
// they are all interpretted as a single argument (rather
// than multiple arguments) to '-e'.
#ifdef _WIN32
needsQuote = strlen(rCommand) > 0 && rCommand[0] != '"';
#endif
std::stringstream command;
if (needsQuote)
command