Skip to content

Commit 69e1664

Browse files
committed
icu, feat: support change TZ/LANG env inside process.
1 parent 6e407d5 commit 69e1664

File tree

3 files changed

+305
-124
lines changed

3 files changed

+305
-124
lines changed

fibjs/src/process/process.cpp

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
#include <unistd.h>
3232
#include "editline/include/editline.h"
3333

34-
extern "C" char** environ;
35-
3634
#define _fileno fileno
3735
inline int32_t _umask(int32_t m)
3836
{
@@ -220,30 +218,6 @@ result_t process_base::get_execPath(exlib::string& retVal)
220218
return 0;
221219
}
222220

223-
result_t process_base::get_env(v8::Local<v8::Object>& retVal)
224-
{
225-
Isolate* isolate = Isolate::current();
226-
v8::Local<v8::Context> context = isolate->context();
227-
228-
if (isolate->m_env.IsEmpty()) {
229-
v8::Local<v8::Object> o = v8::Object::New(isolate->m_isolate);
230-
char** env = environ;
231-
const char *p, *p1;
232-
233-
while ((p = *env++) != NULL) {
234-
p1 = qstrchr(p, '=');
235-
if (p1)
236-
o->Set(context, isolate->NewString(p, (int32_t)(p1 - p)), isolate->NewString(p1 + 1)).Check();
237-
}
238-
239-
isolate->m_env.Reset(isolate->m_isolate, o);
240-
retVal = o;
241-
} else
242-
retVal = v8::Local<v8::Object>::New(isolate->m_isolate, isolate->m_env);
243-
244-
return 0;
245-
}
246-
247221
result_t process_base::get_arch(exlib::string& retVal)
248222
{
249223
return os_base::arch(retVal);

fibjs/src/process/process_env.cpp

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
* process_env.cpp
3+
*
4+
* Created on: Jan 24, 2023
5+
* Author: lion
6+
*/
7+
8+
#include "object.h"
9+
#include "ifs/process.h"
10+
#include "unicode/locid.h"
11+
#include "unicode/timezone.h"
12+
13+
extern "C" char** environ;
14+
15+
namespace fibjs {
16+
17+
inline void on_env_update(exlib::string key, exlib::string val)
18+
{
19+
if (key == "TZ") {
20+
Isolate* isolate = Isolate::current();
21+
22+
icu::TimeZone* zone = icu::TimeZone::createTimeZone(val.c_str());
23+
icu::TimeZone::setDefault(*zone);
24+
25+
isolate->m_isolate->DateTimeConfigurationChangeNotification(v8::Isolate::TimeZoneDetection::kRedetect);
26+
} else if (key == "LANG") {
27+
Isolate* isolate = Isolate::current();
28+
29+
icu::Locale locale(val.c_str());
30+
UErrorCode error_code = U_ZERO_ERROR;
31+
icu::Locale::setDefault(locale, error_code);
32+
33+
isolate->m_isolate->LocaleConfigurationChangeNotification();
34+
}
35+
}
36+
37+
void SetEnv(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info)
38+
{
39+
Isolate* isolate = Isolate::current();
40+
41+
if (!isolate->m_env.IsEmpty()) {
42+
exlib::string key = isolate->toString(property);
43+
exlib::string val = isolate->toString(value);
44+
45+
#ifdef _WIN32
46+
SetEnvironmentVariableA(key.c_str(), val.c_str());
47+
#else
48+
setenv(key.c_str(), val.c_str(), 1);
49+
#endif
50+
on_env_update(key, val);
51+
}
52+
}
53+
54+
void DelEnv(v8::Local<v8::Name> property, const v8::PropertyCallbackInfo<v8::Boolean>& info)
55+
{
56+
Isolate* isolate = Isolate::current();
57+
exlib::string key = isolate->toString(property);
58+
59+
#ifdef _WIN32
60+
SetEnvironmentVariableA(key.c_str(), NULL);
61+
#else
62+
unsetenv(key.c_str());
63+
#endif
64+
on_env_update(key, "");
65+
}
66+
67+
result_t process_base::get_env(v8::Local<v8::Object>& retVal)
68+
{
69+
Isolate* isolate = Isolate::current();
70+
v8::Local<v8::Context> context = isolate->context();
71+
72+
if (isolate->m_env.IsEmpty()) {
73+
v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate->m_isolate);
74+
templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(nullptr, SetEnv, nullptr, DelEnv));
75+
v8::Local<v8::Object> o = templ->GetFunction(context).ToLocalChecked()->NewInstance(context).ToLocalChecked();
76+
char** env = environ;
77+
const char *p, *p1;
78+
79+
while ((p = *env++) != NULL) {
80+
p1 = qstrchr(p, '=');
81+
if (p1)
82+
o->Set(context, isolate->NewString(p, (int32_t)(p1 - p)), isolate->NewString(p1 + 1)).Check();
83+
}
84+
85+
isolate->m_env.Reset(isolate->m_isolate, o);
86+
retVal = o;
87+
} else
88+
retVal = v8::Local<v8::Object>::New(isolate->m_isolate, isolate->m_env);
89+
90+
return 0;
91+
}
92+
93+
}

0 commit comments

Comments
 (0)