[ CLI ] Add support for modifying the environment from package:dartdev

This change makes it possible to set environment variables for the
current process from package:dartdev.

As a proof of concept, package:dartdev now sets `DART_ROOT` to the path
of the Dart SDK in the environment.

Related to https://github.com/dart-lang/sdk/issues/63210 and https://github.com/dart-lang/sdk/issues/62876

TEST=pkg/dartdev/test/environment_test.dart
Change-Id: If3a90279e99dadaba435ae3e43a752dcfda69227
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/499300
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
This commit is contained in:
Ben Konyi
2026-05-05 10:03:41 -07:00
parent 5c3fb10fea
commit c5a57427d1
9 changed files with 122 additions and 3 deletions
+15
View File
@@ -429,6 +429,7 @@ class DartDev {
DartDev_Result_Run = 1,
DartDev_Result_RunExec = 2,
DartDev_Result_Exit = 3,
DartDev_Result_SetEnvironmentVariable = 4,
} DartDev_Result;
static CStringUniquePtr ResolvedDartVmPath() {
@@ -734,6 +735,16 @@ class DartDev {
}
}
static void SetEnvironmentVariableCallback(Dart_CObject* message) {
ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
const char* name = GetArrayItem(message, 1)->value.as_string;
const char* value = nullptr;
if (GetArrayItem(message, 2)->type == Dart_CObject_kString) {
value = GetArrayItem(message, 2)->value.as_string;
}
Platform::SetEnvironmentVariable(name, value);
}
// Callback that processes the result from execution of dartdev
//
static void ResultCallback(Dart_Port dest_port_id, Dart_CObject* message) {
@@ -754,6 +765,10 @@ class DartDev {
ExitResultCallback(message);
break;
}
case DartDev_Result_SetEnvironmentVariable: {
SetEnvironmentVariableCallback(message);
break;
}
default:
UNREACHABLE();
}
+2
View File
@@ -110,6 +110,8 @@ class Platform {
static void SetCoreDumpResourceLimit(int value);
static bool SetEnvironmentVariable(const char* name, const char* value);
private:
// The path to the executable.
static const char* executable_name_;
+7
View File
@@ -215,6 +215,13 @@ void Platform::SetCoreDumpResourceLimit(int value) {
setrlimit(RLIMIT_CORE, &limit);
}
bool Platform::SetEnvironmentVariable(const char* name, const char* value) {
if (value == nullptr) {
return unsetenv(name) == 0;
}
return setenv(name, value, 0) == 0;
}
} // namespace bin
} // namespace dart
+7
View File
@@ -408,6 +408,13 @@ void Platform::SetCoreDumpResourceLimit(int value) {
setrlimit(RLIMIT_CORE, &limit);
}
bool Platform::SetEnvironmentVariable(const char* name, const char* value) {
if (value == nullptr) {
return unsetenv(name) == 0;
}
return setenv(name, value, 0) == 0;
}
} // namespace bin
} // namespace dart
+13
View File
@@ -430,6 +430,19 @@ void Platform::SetCoreDumpResourceLimit(int value) {
// Not supported.
}
bool Platform::SetEnvironmentVariable(const char* name, const char* value) {
std::unique_ptr<wchar_t[]> name_w = Utf8ToWideChar(name);
if (value == nullptr) {
return ::SetEnvironmentVariableW(name_w.get(), nullptr) != 0;
}
DWORD ret = ::GetEnvironmentVariableW(name_w.get(), nullptr, 0);
if (ret == 0 && ::GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
std::unique_ptr<wchar_t[]> value_w = Utf8ToWideChar(value);
return ::SetEnvironmentVariableW(name_w.get(), value_w.get()) != 0;
}
return true;
}
} // namespace bin
} // namespace dart