@@ -109,6 +109,31 @@ static void SafeGetenv(const FunctionCallbackInfo<Value>& args) {
109109 args.GetReturnValue ().Set (result);
110110}
111111
112+ static void GetTempDir (const FunctionCallbackInfo<Value>& args) {
113+ Environment* env = Environment::GetCurrent (args);
114+ Isolate* isolate = env->isolate ();
115+
116+ std::string dir;
117+
118+ // Let's wrap SafeGetEnv since it returns true for empty string.
119+ auto get_env = [&dir, &env](std::string_view key) {
120+ USE (SafeGetenv (key.data (), &dir, env->env_vars ()));
121+ return !dir.empty ();
122+ };
123+
124+ // Try TMPDIR, TMP, and TEMP in that order.
125+ if (!get_env (" TMPDIR" ) && !get_env (" TMP" ) && !get_env (" TEMP" )) {
126+ return ;
127+ }
128+
129+ if (dir.size () > 1 && dir.ends_with (" /" )) {
130+ dir.pop_back ();
131+ }
132+
133+ args.GetReturnValue ().Set (
134+ ToV8Value (isolate->GetCurrentContext (), dir).ToLocalChecked ());
135+ }
136+
112137#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
113138
114139static const uid_t uid_not_found = static_cast <uid_t >(-1 );
@@ -456,6 +481,7 @@ static void InitGroups(const FunctionCallbackInfo<Value>& args) {
456481
457482void RegisterExternalReferences (ExternalReferenceRegistry* registry) {
458483 registry->Register (SafeGetenv);
484+ registry->Register (GetTempDir);
459485
460486#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
461487 registry->Register (GetUid);
@@ -478,6 +504,7 @@ static void Initialize(Local<Object> target,
478504 Local<Context> context,
479505 void * priv) {
480506 SetMethod (context, target, " safeGetenv" , SafeGetenv);
507+ SetMethod (context, target, " getTempDir" , GetTempDir);
481508
482509#ifdef NODE_IMPLEMENTS_POSIX_CREDENTIALS
483510 Environment* env = Environment::GetCurrent (context);
0 commit comments