@@ -43,9 +43,7 @@ impl Command {
4343 unsafe {
4444 self . inner . pre_exec ( move || {
4545 let rlp = libc:: rlimit { rlim_cur : max as _ , rlim_max : max as _ } ;
46- if libc:: setrlimit ( libc:: RLIMIT_AS , & rlp) != 0 {
47- return Err ( io:: Error :: last_os_error ( ) ) ;
48- }
46+ libc:: setrlimit ( libc:: RLIMIT_AS , & rlp) ;
4947 Ok ( ( ) )
5048 } ) ;
5149 }
@@ -55,29 +53,46 @@ impl Command {
5553
5654 #[ cfg( windows) ]
5755 fn spawn ( & mut self ) -> io:: Result < Child > {
58- unsafe {
59- let job = CreateJobObjectW ( std:: ptr:: null_mut ( ) , std:: ptr:: null ( ) ) ;
60-
61- let mut info: JOBOBJECT_EXTENDED_LIMIT_INFORMATION = std:: mem:: zeroed ( ) ;
62- info. BasicLimitInformation . LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY ;
63- info. ProcessMemoryLimit = 536870912 ; // 512MB
64-
65- SetInformationJobObject (
66- job,
67- JobObjectExtendedLimitInformation ,
68- & mut info as * mut _ as * mut _ ,
69- std:: mem:: size_of :: < JOBOBJECT_EXTENDED_LIMIT_INFORMATION > ( ) as u32 ,
70- ) ;
56+ use std:: os:: windows:: io:: RawHandle ;
7157
72- let mut child =
73- Command :: new ( "your_program" ) . args ( & [ "arg1" , "arg2" ] ) . stdout ( Stdio :: piped ( ) ) . spawn ( ) ?;
58+ use windows_sys:: Win32 :: System :: JobObjects :: { AssignProcessToJobObject , CreateJobObjectW , JOB_OBJECT_LIMIT_PROCESS_MEMORY , JOBOBJECT_EXTENDED_LIMIT_INFORMATION , JobObjectExtendedLimitInformation , SetInformationJobObject } ;
7459
75- AssignProcessToJobObject ( job, child. as_raw_handle ( ) as HANDLE ) ;
60+ fn assign_job ( max : usize , handle : RawHandle ) -> io:: Result < RawHandle > {
61+ unsafe {
62+ let job = CreateJobObjectW ( std:: ptr:: null_mut ( ) , std:: ptr:: null ( ) ) ;
63+ if job. is_null ( ) {
64+ return Err ( io:: Error :: last_os_error ( ) ) ;
65+ }
7666
77- let status = child. wait ( ) ?;
67+ let mut info: JOBOBJECT_EXTENDED_LIMIT_INFORMATION = std:: mem:: zeroed ( ) ;
68+ info. BasicLimitInformation . LimitFlags = JOB_OBJECT_LIMIT_PROCESS_MEMORY ;
69+ info. ProcessMemoryLimit = max;
70+
71+ let result = SetInformationJobObject (
72+ job,
73+ JobObjectExtendedLimitInformation ,
74+ & mut info as * mut _ as * mut _ ,
75+ std:: mem:: size_of_val ( & info) as u32 ,
76+ ) ;
77+
78+ if result == 0 {
79+ Err ( io:: Error :: last_os_error ( ) )
80+ } else if AssignProcessToJobObject ( job, handle) == 0 {
81+ Err ( io:: Error :: last_os_error ( ) )
82+ } else {
83+ Ok ( job)
84+ }
85+ }
86+ }
7887
79- CloseHandle ( job) ;
88+ let child = self . inner . spawn ( ) ?;
89+ if let ( Some ( max) , Some ( handle) ) = ( self . memory , child. raw_handle ( ) ) {
90+ if let Ok ( job) = assign_job ( max, handle) {
91+ return Ok ( Child :: new ( child, Some ( job) ) ) ;
92+ }
8093 }
94+
95+ Ok ( Child :: new ( child, None ) )
8196 }
8297
8398 async fn output ( & mut self ) -> io:: Result < std:: process:: Output > {
0 commit comments