@@ -897,8 +897,18 @@ fn delete_rustup_and_cargo_home() -> Result<()> {
897
897
// https://stackoverflow.com/questions/10319526/understanding-a-self-deleting-program-in-c
898
898
#[ cfg( windows) ]
899
899
fn delete_rustup_and_cargo_home ( ) -> Result < ( ) > {
900
+ use std:: io;
901
+ use std:: mem;
902
+ use std:: os:: windows:: ffi:: OsStrExt ;
903
+ use std:: ptr;
900
904
use std:: thread;
901
905
use std:: time:: Duration ;
906
+ use winapi:: shared:: minwindef:: DWORD ;
907
+ use winapi:: um:: fileapi:: { CreateFileW , OPEN_EXISTING } ;
908
+ use winapi:: um:: handleapi:: { CloseHandle , INVALID_HANDLE_VALUE } ;
909
+ use winapi:: um:: minwinbase:: SECURITY_ATTRIBUTES ;
910
+ use winapi:: um:: winbase:: FILE_FLAG_DELETE_ON_CLOSE ;
911
+ use winapi:: um:: winnt:: { FILE_SHARE_DELETE , FILE_SHARE_READ , GENERIC_READ } ;
902
912
903
913
// CARGO_HOME, hopefully empty except for bin/rustup.exe
904
914
let cargo_home = utils:: cargo_home ( ) ?;
@@ -914,32 +924,20 @@ fn delete_rustup_and_cargo_home() -> Result<()> {
914
924
// of CARGO_HOME.
915
925
let numbah: u32 = rand:: random ( ) ;
916
926
let gc_exe = work_path. join ( & format ! ( "rustup-gc-{:x}.exe" , numbah) ) ;
927
+ // Copy rustup (probably this process's exe) to the gc exe
928
+ utils:: copy_file ( & rustup_path, & gc_exe) ?;
929
+ let gc_exe_win: Vec < _ > = gc_exe. as_os_str ( ) . encode_wide ( ) . chain ( Some ( 0 ) ) . collect ( ) ;
930
+
931
+ // Make the sub-process opened by gc exe inherit its attribute.
932
+ let mut sa = SECURITY_ATTRIBUTES {
933
+ nLength : mem:: size_of :: < SECURITY_ATTRIBUTES > as DWORD ,
934
+ lpSecurityDescriptor : ptr:: null_mut ( ) ,
935
+ bInheritHandle : 1 ,
936
+ } ;
917
937
918
- use std:: io;
919
- use std:: mem;
920
- use std:: os:: windows:: ffi:: OsStrExt ;
921
- use std:: ptr;
922
- use winapi:: shared:: minwindef:: DWORD ;
923
- use winapi:: um:: fileapi:: { CreateFileW , OPEN_EXISTING } ;
924
- use winapi:: um:: handleapi:: { CloseHandle , INVALID_HANDLE_VALUE } ;
925
- use winapi:: um:: minwinbase:: SECURITY_ATTRIBUTES ;
926
- use winapi:: um:: winbase:: FILE_FLAG_DELETE_ON_CLOSE ;
927
- use winapi:: um:: winnt:: { FILE_SHARE_DELETE , FILE_SHARE_READ , GENERIC_READ } ;
928
-
929
- unsafe {
930
- // Copy rustup (probably this process's exe) to the gc exe
931
- utils:: copy_file ( & rustup_path, & gc_exe) ?;
932
-
933
- let mut gc_exe_win: Vec < _ > = gc_exe. as_os_str ( ) . encode_wide ( ) . collect ( ) ;
934
- gc_exe_win. push ( 0 ) ;
935
-
938
+ let _g = unsafe {
936
939
// Open an inheritable handle to the gc exe marked
937
- // FILE_FLAG_DELETE_ON_CLOSE. This will be inherited
938
- // by subsequent processes.
939
- let mut sa = mem:: zeroed :: < SECURITY_ATTRIBUTES > ( ) ;
940
- sa. nLength = mem:: size_of :: < SECURITY_ATTRIBUTES > ( ) as DWORD ;
941
- sa. bInheritHandle = 1 ;
942
-
940
+ // FILE_FLAG_DELETE_ON_CLOSE.
943
941
let gc_handle = CreateFileW (
944
942
gc_exe_win. as_ptr ( ) ,
945
943
GENERIC_READ ,
@@ -955,23 +953,23 @@ fn delete_rustup_and_cargo_home() -> Result<()> {
955
953
return Err ( err) . chain_err ( || ErrorKind :: WindowsUninstallMadness ) ;
956
954
}
957
955
958
- let _g = scopeguard:: guard ( gc_handle, |h| {
956
+ scopeguard:: guard ( gc_handle, |h| {
959
957
let _ = CloseHandle ( h) ;
960
- } ) ;
958
+ } )
959
+ } ;
961
960
962
- Command :: new ( gc_exe)
963
- . spawn ( )
964
- . chain_err ( || ErrorKind :: WindowsUninstallMadness ) ?;
961
+ Command :: new ( gc_exe)
962
+ . spawn ( )
963
+ . chain_err ( || ErrorKind :: WindowsUninstallMadness ) ?;
965
964
966
- // The catch 22 article says we must sleep here to give
967
- // Windows a chance to bump the processes file reference
968
- // count. acrichto though is in disbelief and *demanded* that
969
- // we not insert a sleep. If Windows failed to uninstall
970
- // correctly it is because of him.
965
+ // The catch 22 article says we must sleep here to give
966
+ // Windows a chance to bump the processes file reference
967
+ // count. acrichto though is in disbelief and *demanded* that
968
+ // we not insert a sleep. If Windows failed to uninstall
969
+ // correctly it is because of him.
971
970
972
- // (.. and months later acrichto owes me a beer).
973
- thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
974
- }
971
+ // (.. and months later acrichto owes me a beer).
972
+ thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
975
973
976
974
Ok ( ( ) )
977
975
}
@@ -1027,23 +1025,23 @@ fn wait_for_parent() -> Result<()> {
1027
1025
return Err ( err) . chain_err ( || ErrorKind :: WindowsUninstallMadness ) ;
1028
1026
}
1029
1027
1030
- let _g = scopeguard:: guard ( snapshot, |h| {
1028
+ let snapshot = scopeguard:: guard ( snapshot, |h| {
1031
1029
let _ = CloseHandle ( h) ;
1032
1030
} ) ;
1033
1031
1034
1032
let mut entry: PROCESSENTRY32 = mem:: zeroed ( ) ;
1035
1033
entry. dwSize = mem:: size_of :: < PROCESSENTRY32 > ( ) as DWORD ;
1036
1034
1037
1035
// Iterate over system processes looking for ours
1038
- let success = Process32First ( snapshot, & mut entry) ;
1036
+ let success = Process32First ( * snapshot, & mut entry) ;
1039
1037
if success == 0 {
1040
1038
let err = io:: Error :: last_os_error ( ) ;
1041
1039
return Err ( err) . chain_err ( || ErrorKind :: WindowsUninstallMadness ) ;
1042
1040
}
1043
1041
1044
1042
let this_pid = GetCurrentProcessId ( ) ;
1045
1043
while entry. th32ProcessID != this_pid {
1046
- let success = Process32Next ( snapshot, & mut entry) ;
1044
+ let success = Process32Next ( * snapshot, & mut entry) ;
1047
1045
if success == 0 {
1048
1046
let err = io:: Error :: last_os_error ( ) ;
1049
1047
return Err ( err) . chain_err ( || ErrorKind :: WindowsUninstallMadness ) ;
@@ -1062,12 +1060,12 @@ fn wait_for_parent() -> Result<()> {
1062
1060
return Ok ( ( ) ) ;
1063
1061
}
1064
1062
1065
- let _g = scopeguard:: guard ( parent, |h| {
1063
+ let parent = scopeguard:: guard ( parent, |h| {
1066
1064
let _ = CloseHandle ( h) ;
1067
1065
} ) ;
1068
1066
1069
1067
// Wait for our parent to exit
1070
- let res = WaitForSingleObject ( parent, INFINITE ) ;
1068
+ let res = WaitForSingleObject ( * parent, INFINITE ) ;
1071
1069
1072
1070
if res != WAIT_OBJECT_0 {
1073
1071
let err = io:: Error :: last_os_error ( ) ;
0 commit comments