@@ -530,77 +530,77 @@ pub const FileSystem = struct {
530530 file_limit : usize = 32 ,
531531 file_quota : usize = 32 ,
532532
533- pub var win_tempdir_cache : ? []const u8 = undefined ;
533+ fn #platformTempDir () []const u8 {
534+ // Try TMPDIR, TMP, and TEMP in that order, matching Node.js.
535+ // https://github.com/nodejs/node/blob/e172be269890702bf2ad06252f2f152e7604d76c/src/node_credentials.cc#L132
536+ if (bun .env_var .TMPDIR .getNotEmpty () orelse
537+ bun .env_var .TMP .getNotEmpty () orelse
538+ bun .env_var .TEMP .getNotEmpty ()) | dir |
539+ {
540+ if (dir .len > 1 and dir [dir .len - 1 ] == std .fs .path .sep ) {
541+ return dir [0 .. dir .len - 1 ];
542+ }
543+
544+ return dir ;
545+ }
534546
535- pub fn platformTempDir () []const u8 {
536547 return switch (Environment .os ) {
537548 // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw#remarks
538- .windows = > win_tempdir_cache orelse {
539- const value = bun .env_var .TEMP .get () orelse bun .env_var .TMP .get () orelse brk : {
540- if (bun .env_var .SYSTEMROOT .get () orelse bun .env_var .WINDIR .get ()) | windir | {
541- break :brk std .fmt .allocPrint (
542- bun .default_allocator ,
543- "{s}\\ Temp" ,
544- .{strings .withoutTrailingSlash (windir )},
545- ) catch | err | bun .handleOom (err );
546- }
547-
548- if (bun .env_var .HOME .get ()) | profile | {
549- var buf : bun.PathBuffer = undefined ;
550- var parts = [_ ]string {"AppData\\ Local\\ Temp" };
551- const out = bun .path .joinAbsStringBuf (profile , & buf , & parts , .loose );
552- break :brk bun .handleOom (bun .default_allocator .dupe (u8 , out ));
553- }
554-
555- var tmp_buf : bun.PathBuffer = undefined ;
556- const cwd = std .posix .getcwd (& tmp_buf ) catch @panic ("Failed to get cwd for platformTempDir" );
557- const root = bun .path .windowsFilesystemRoot (cwd );
558- break :brk std .fmt .allocPrint (
549+ .windows = > {
550+ if (bun .env_var .SYSTEMROOT .get () orelse bun .env_var .WINDIR .get ()) | windir | {
551+ return std .fmt .allocPrint (
559552 bun .default_allocator ,
560- "{s}\\ Windows \\ Temp" ,
561- .{strings .withoutTrailingSlash (root )},
553+ "{s}\\ Temp" ,
554+ .{strings .withoutTrailingSlash (windir )},
562555 ) catch | err | bun .handleOom (err );
563- };
564- win_tempdir_cache = value ;
565- return value ;
556+ }
557+
558+ if (bun .env_var .HOME .get ()) | profile | {
559+ var buf : bun.PathBuffer = undefined ;
560+ var parts = [_ ]string {"AppData\\ Local\\ Temp" };
561+ const out = bun .path .joinAbsStringBuf (profile , & buf , & parts , .loose );
562+ return bun .handleOom (bun .default_allocator .dupe (u8 , out ));
563+ }
564+
565+ var tmp_buf : bun.PathBuffer = undefined ;
566+ const cwd = std .posix .getcwd (& tmp_buf ) catch @panic ("Failed to get cwd for platformTempDir" );
567+ const root = bun .path .windowsFilesystemRoot (cwd );
568+ return std .fmt .allocPrint (
569+ bun .default_allocator ,
570+ "{s}\\ Windows\\ Temp" ,
571+ .{strings .withoutTrailingSlash (root )},
572+ ) catch | err | bun .handleOom (err );
566573 },
567574 .mac = > "/private/tmp" ,
568575 else = > "/tmp" ,
569576 };
570577 }
571578
579+ var get_platform_tempdir = bun .once (#platformTempDir );
580+ pub fn platformTempDir () []const u8 {
581+ return get_platform_tempdir .call (.{});
582+ }
583+
572584 pub const Tmpfile = switch (Environment .os ) {
573585 .windows = > TmpfileWindows ,
574586 else = > TmpfilePosix ,
575587 };
576588
577- pub var tmpdir_path : []const u8 = undefined ;
578- pub var tmpdir_path_set = false ;
579- pub fn tmpdirPath (_ : * const @This ()) []const u8 {
580- if (! tmpdir_path_set ) {
581- tmpdir_path = bun .env_var .BUN_TMPDIR .get () orelse platformTempDir ();
582- tmpdir_path_set = true ;
583- }
584-
585- return tmpdir_path ;
589+ pub fn tmpdirPath () []const u8 {
590+ return bun .env_var .BUN_TMPDIR .getNotEmpty () orelse platformTempDir ();
586591 }
587592
588593 pub fn openTmpDir (_ : * const RealFS ) ! std.fs.Dir {
589- if (! tmpdir_path_set ) {
590- tmpdir_path = bun .env_var .BUN_TMPDIR .get () orelse platformTempDir ();
591- tmpdir_path_set = true ;
592- }
593-
594594 if (comptime Environment .isWindows ) {
595- return (try bun .sys .openDirAtWindowsA (bun .invalid_fd , tmpdir_path , .{
595+ return (try bun .sys .openDirAtWindowsA (bun .invalid_fd , tmpdirPath () , .{
596596 .iterable = true ,
597597 // we will not delete the temp directory
598598 .can_rename_or_delete = false ,
599599 .read_only = true ,
600600 }).unwrap ()).stdDir ();
601601 }
602602
603- return try bun .openDirAbsolute (tmpdir_path );
603+ return try bun .openDirAbsolute (tmpdirPath () );
604604 }
605605
606606 pub fn entriesAt (this : * RealFS , index : allocators.IndexType , generation : bun.Generation ) ? * EntriesOption {
@@ -639,11 +639,6 @@ pub const FileSystem = struct {
639639 return bun .env_var .BUN_TMPDIR .get () orelse platformTempDir ();
640640 }
641641
642- pub fn setTempdir (path : ? string ) void {
643- tmpdir_path = path orelse getDefaultTempDir ();
644- tmpdir_path_set = true ;
645- }
646-
647642 pub const TmpfilePosix = struct {
648643 fd : bun.FileDescriptor = bun .invalid_fd ,
649644 dir_fd : bun.FileDescriptor = bun .invalid_fd ,
0 commit comments