@@ -575,13 +575,14 @@ def _install_binary_into_bin_dir(binary_tmp, target_bin, src_hash: str, debug: b
575575 target_bin = Path (target_bin )
576576
577577 _exe = ".exe" if sys .platform == "win32" else ""
578- all_succeeded = True # <-- NEW: Track if all binaries successfully update
578+ all_succeeded = True # Track if all binaries successfully updated
579+ any_hard_failed = False # True only for failures that aren't "file in use"
579580
580581 for name in ("8pkg" , "omnipkg" , "OMNIPKG" , "8PKG" ):
581582 target = target_bin / (name + _exe )
582583 if target .exists ():
583584 try :
584- # NEW: Windows file lock bypass: Rename the running executable first
585+ # Windows file lock bypass: Rename the running executable first
585586 if sys .platform == "win32" :
586587 old_target = target .with_name (target .name + ".old" )
587588 try :
@@ -590,18 +591,31 @@ def _install_binary_into_bin_dir(binary_tmp, target_bin, src_hash: str, debug: b
590591 target .rename (old_target )
591592 except Exception :
592593 pass
593-
594+
594595 shutil .copy2 (str (binary_tmp ), str (target ))
595596 if sys .platform != "win32" :
596597 os .chmod (str (target ), 0o755 )
597598 replaced .append (str (target ))
598599 except Exception as e :
599- all_succeeded = False # <-- NEW: Mark as failed!
600+ all_succeeded = False
601+ # WinError 32 = file in use = the process is currently running
602+ # from this exe. That's expected and harmless — the .old rename
603+ # trick means the next cold-start will pick up the new binary.
604+ # Don't treat this as a hard failure that blocks the marker write.
605+ is_file_in_use = (
606+ sys .platform == "win32"
607+ and hasattr (e , "winerror" )
608+ and e .winerror == 32
609+ )
610+ if not is_file_in_use :
611+ any_hard_failed = True
600612 if debug :
601613 print (f"[C-INSTALL] could not replace { target } : { e } " , file = sys .stderr )
602614
603- # NEW: ONLY write the marker if every replacement succeeded
604- if replaced and all_succeeded and src_hash and c_src :
615+ # Write the marker as long as we replaced at least one binary and had no
616+ # hard failures. WinError 32 (file-in-use on the running exe) is not a
617+ # hard failure — it's expected and already handled by the .old rename.
618+ if replaced and not any_hard_failed and src_hash and c_src :
605619 try :
606620 (target_bin / ".omnipkg_dispatch_compiled" ).write_text (
607621 f"{ src_hash } :{ c_src } " , encoding = "utf-8"
@@ -649,15 +663,15 @@ def _push_binary_to_bin_dir(native_bin, target_bin, src_hash: str, debug: bool)
649663 if debug :
650664 print (f"[C-INSTALL] push: { src_binary } -> { target_bin } " , file = sys .stderr )
651665
652- replaced = []
666+ replaced = []
653667 _exe = ".exe" if sys .platform == "win32" else ""
654- all_succeeded = True # <-- NEW
655-
668+ any_hard_failed = False
669+
656670 for name in ("8pkg" , "omnipkg" , "OMNIPKG" , "8PKG" ):
657671 target = target_bin / (name + _exe )
658672 if target .exists ():
659673 try :
660- # NEW: Windows rename trick
674+ # Windows rename trick
661675 if sys .platform == "win32" :
662676 old_target = target .with_name (target .name + ".old" )
663677 try :
@@ -675,11 +689,17 @@ def _push_binary_to_bin_dir(native_bin, target_bin, src_hash: str, debug: bool)
675689 os .chmod (str (target ), 0o755 )
676690 replaced .append (name )
677691 except Exception as e :
678- all_succeeded = False # <-- NEW
692+ is_file_in_use = (
693+ sys .platform == "win32"
694+ and hasattr (e , "winerror" )
695+ and e .winerror == 32
696+ )
697+ if not is_file_in_use :
698+ any_hard_failed = True
679699 if debug :
680700 print (f"[C-INSTALL] push: could not replace { target } : { e } " , file = sys .stderr )
681701
682- if replaced and all_succeeded and src_hash :
702+ if replaced and not any_hard_failed and src_hash :
683703 try :
684704 (target_bin / ".omnipkg_dispatch_compiled" ).write_text (src_hash , encoding = "utf-8" )
685705 if debug :
0 commit comments