@@ -464,6 +464,25 @@ void CompileCacheHandler::Persist() {
464464 continue ;
465465 }
466466 Debug (" -> %s\n " , mkstemp_req.path );
467+
468+ // Close the temporary file descriptor if it is still open, and unlink
469+ // the temporary file unless the rename below succeeds, so a failed
470+ // persistence attempt does not leak the descriptor or leave the
471+ // temporary file behind.
472+ bool tmp_fd_needs_close = true ;
473+ bool tmp_renamed = false ;
474+ auto cleanup_tmp_file = OnScopeLeave ([&]() {
475+ if (tmp_fd_needs_close) {
476+ uv_fs_t req;
477+ uv_fs_close (nullptr , &req, mkstemp_req.result , nullptr );
478+ uv_fs_req_cleanup (&req);
479+ }
480+ if (!tmp_renamed) {
481+ uv_fs_t req;
482+ uv_fs_unlink (nullptr , &req, mkstemp_req.path , nullptr );
483+ uv_fs_req_cleanup (&req);
484+ }
485+ });
467486 Debug (" [compile cache] writing cache for %s %s to temporary file %s [%d "
468487 " %d %d "
469488 " %d %d]..." ,
@@ -496,6 +515,7 @@ void CompileCacheHandler::Persist() {
496515 auto cleanup_close =
497516 OnScopeLeave ([&close_req]() { uv_fs_req_cleanup (&close_req); });
498517 err = uv_fs_close (nullptr , &close_req, mkstemp_req.result , nullptr );
518+ tmp_fd_needs_close = false ;
499519
500520 if (err < 0 ) {
501521 Debug (" failed: %s\n " , uv_strerror (err));
@@ -521,6 +541,7 @@ void CompileCacheHandler::Persist() {
521541 Debug (" failed: %s\n " , uv_strerror (err));
522542 continue ;
523543 }
544+ tmp_renamed = true ;
524545 Debug (" success\n " );
525546 entry->persisted = true ;
526547 }
0 commit comments