1 /*
2 * ServerREnvironment.cpp
3 *
4 * Copyright (C) 2021 by RStudio, PBC
5 *
6 * Unless you have received this program directly from RStudio pursuant
7 * to the terms of a commercial license agreement with RStudio, then
8 * this program is licensed to you under the terms of version 3 of the
9 * GNU Affero General Public License. This program is distributed WITHOUT
10 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
11 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
12 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
13 *
14 */
15
16 #include "ServerREnvironment.hpp"
17
18 #include <shared_core/Error.hpp>
19 #include <core/Log.hpp>
20 #include <core/Thread.hpp>
21 #include <core/r_util/REnvironment.hpp>
22
23 #include <server_core/RVersionsScanner.hpp>
24
25 #include <server/ServerOptions.hpp>
26 #include <server/ServerUriHandlers.hpp>
27
28 using namespace rstudio::core;
29
30 namespace rstudio {
31 namespace server {
32 namespace r_environment {
33
34 namespace {
35
36 boost::mutex s_versionMutex;
37
38 // R version detected during initialization (either the system
39 // R version or the provided fallback)
40 core::r_util::RVersion s_rVersion;
41
42 boost::shared_ptr<RVersionsScanner> s_scanner;
43
44 } // anonymous namespace
45
initializeScanner()46 void initializeScanner()
47 {
48 s_scanner.reset(
49 new RVersionsScanner(true,
50 options().rsessionWhichR(),
51 options().rldpathPath(),
52 options().rsessionLdLibraryPath()));
53 }
54
initialize(std::string * pErrMsg)55 bool initialize(std::string* pErrMsg)
56 {
57 if (!s_scanner)
58 initializeScanner();
59
60 // if we already have a cached version (such as multi version setting it)
61 // then simply return success
62 if (!s_rVersion.empty())
63 {
64 return true;
65 }
66
67 // otherwise, we have no cached version (no multi version)
68 // detect it ourselves
69 bool detected = s_scanner->detectSystemRVersion(&s_rVersion, pErrMsg);
70 return detected;
71 }
72
rVersion()73 core::r_util::RVersion rVersion()
74 {
75 LOCK_MUTEX(s_versionMutex)
76 {
77 return s_rVersion;
78 }
79 END_LOCK_MUTEX
80
81 // mutex related error
82 return r_util::RVersion();
83 }
84
setRVersion(const r_util::RVersion & version)85 void setRVersion(const r_util::RVersion& version)
86 {
87 LOCK_MUTEX(s_versionMutex)
88 {
89 s_rVersion = version;
90 }
91 END_LOCK_MUTEX
92 }
93
detectRVersion(const core::FilePath & rScriptPath,core::r_util::RVersion * pVersion,std::string * pErrMsg)94 bool detectRVersion(const core::FilePath& rScriptPath,
95 core::r_util::RVersion* pVersion,
96 std::string* pErrMsg)
97 {
98 if (!s_scanner)
99 initializeScanner();
100
101 return s_scanner->detectRVersion(rScriptPath, pVersion, pErrMsg);
102 }
103
104 } // namespace r_environment
105 } // namespace server
106 } // namespace rstudio
107
108