package Ġgro ost av . kotlin x . exec Ċ Ċ import Ġkotlinx . coroutines .* Ċ import Ġkotlinx . coroutines . channels . Buffer Overflow Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . channels . Channel Result Ċ import Ġkotlinx . coroutines . flow . Flow Ċ import Ġkotlinx . coroutines . flow . Flow Collector Ċ import Ġkotlinx . coroutines . flow . receive As Flow Ċ import Ġkotlinx . coroutines . select s . Select Clause 0 Ċ import Ġkotlinx . coroutines . select s . Select Clause 1 Ċ import Ġkotlinx . coroutines . select s . Select Instance Ċ import Ġjava . io . IOException Ċ import Ġjava . lang . IllegalArgumentException Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġjava . util . concurrent . atomic . Atomic Reference Ċ import Ġkotlin . coroutines .* Ċ Ċ @ Opt In ( Internal Cor outines Api :: class ) Ċ class ĠExec Coroutine ( ĊĠĠĠ Ġcontext : ĠCor outine Context , ĊĠĠĠ Ġval Ġconfig : ĠProcess Configuration , ĊĠĠĠ Ġprivate Ġval Ġchannel : ĠChannel < Process Event > Ġ= ĠChannel < Process Event >( ĊĠĠĠĠĠĠĠ Ġcapacity Ġ= Ġconfig . aggregate Output Buffer Line Count , ĊĠĠĠĠĠĠĠ Ġon Buffer Overflow Ġ= ĠBuffer Overflow . DROP _ OL DEST ĊĠĠĠ Ġ) Ċ ): ĠAbstract Coroutine < Int ? >( context , Ġinit Parent Job Ġ= Ġtrue , Ġactive Ġ= Ġfalse ), ĠRunning Process , ĠFlow < Process Event > Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( config . command . isNotEmpty ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġrecent Errors Ġ= ĠCircular Array < String >( config . lines For Exception Error ) ĊĊĠĠĠ Ġinternal Ġlateinit Ġvar Ġprocess : ĠProcess ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġhandle : ĠProcess Handle ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġout : ĠNamed Tracing Process Reader ĊĠĠĠ Ġprivate Ġlateinit Ġvar Ġerr : ĠNamed Tracing Process Reader ĊĊĠĠĠ Ġprivate Ġval Ġout Messages Ġ= ĠOutput Parser ( config . de limiters ) ĊĠĠĠ Ġprivate Ġval Ġerr Messages Ġ= ĠOutput Parser ( config . de limiters ) ĊĊĠĠĠ Ġprivate Ġvar Ġprocess State : ĠAtomic Reference < State > Ġ= ĠAtomic Reference ( Not Started ) ĊĊĠĠĠ Ġ// ĠTODO Ġthis Ġshould Ġprobably Ġbe Ġon Ġthe Ġstate Ġobject ... ĊĠĠĠ Ġ// Ġthe Ġonly Ġplace Ġthis Ġfield Ġis Ġupdated Ġis Ġin ĠonStart (), Ġso Ġits Ġprobably Ġsafe ? ĊĠĠĠ Ġ// Ġaside Ġfrom Ġthat Ġwe Ġuse Ġan Ġimmutable Ġcopy Ġand Ġthrow Ġit Ġdown - sus pension , Ġ( eg Ġcollect (), Ġawait ()) ĊĠĠĠ Ġprivate Ġvar Ġtracing Ġ= Ġrun Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġname Ġ= Ġconfig . command . first (). split ("/", Ġ"\ \" ). last (). take ( 3 0 ) ĊĠĠĠĠĠĠĠ Ġcoroutine Context [ Coroutine Tracer ]?. append Name ( name ) Ġ?: ĠCor outine Tracer ( name ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġprocess ID : ĠLong Ġget () Ġ= Ġhandle . pid () ĊĊĠĠĠ Ġ// Ġkotlinx Ġcor outines Ġguarantee : Ġthis Ġwill Ġonly Ġbe Ġcalled Ġonce ĊĠĠĠ Ġoverride Ġfun ĠonStart () Ġ= Ġdo Tracing < Unit >(" onStart ") Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ// Ġeven Ġthough Ġon start () Ġcant Ġbe Ġcalled Ġtwice , ĊĠĠĠĠĠĠĠ Ġ// Ġwe Ġcould Ġbe Ġcancelled Ġwhile ĠonStart - ing . ĊĠĠĠĠĠĠĠ Ġval ĠnewState Ġ= Ġprocess State . update AndGet Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> ĠRunning () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠClosed Ġ-> Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported , Ġis ĠBe ing K illed , Ġis ĠRunning Ġ-> ĠTODO (" state =$ state ĠonStart () ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġwhen Ġ( newState ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . tracing Ġ= Ġthis . tracing . mark (" start ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprocess Builder Ġ= ĠProcess Builder ( config . command ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. directory ( config . working Directory . to File ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( config . environment Ġ!== ĠInherit ed Default Environment ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġenvironment (). apply Ġ{ Ġclear (); Ġput All ( config . environment ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproc Start Result Ġ/* Ġ: Throwable | Process Ġ*/ Ġ= Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// TODO : Ġis Ġthere Ġa Ġnon Ġplatform Ġspecific Ġway Ġto Ġfind Ġout Ġif Ġthe Ġcommand Ġis Ġon Ġthe ĠPATH ? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġthere Ġwas , Ġand Ġit Ġwas Ġreliable , Ġit Ġwould Ġbe Ġnice Ġto Ġturn Ġan ĠIOException : Ġcant Ġfind Ġthat Ġcommand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġinto Ġan Ġillegal Ġargument Ġexception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Builder . start () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcatch ( ex : ĠIOException ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( proc Start Result ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠProcess Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġwe Ġhave Ġa Ġrace Ġcondition Ġhere ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġafter Ġprocess . start (), Ġthe Ġsub Ġprocess Ġmay ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġalready Ġbe Ġf lood ing Ġits Ġstandard - output . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġreally Ġdont Ġwant Ġto Ġbe Ġdoing Ġany Ġwork Ġafter Ġprocess . start () Ġso Ġthat Ġwe Ġcan Ġget Ġto ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġreading Ġits Ġoutput Ġas ap . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġthus , Ġwe Ġshould Ġwork Ġto Ġoptimize Ġthe Ġtime - to - attachment Ġhere , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbut Ġcan Ġwe Ġrepro Ġthat Ġin Ġsome Ġkind Ġof Ġtest Ġenvironment ? ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess Ġ= Ġproc Start Result ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Ġ= Ġproc Start Result . to Handle () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . tracing Ġ= Ġthis . tracing . append Name ( handle . pid (). toString ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġerr Ġ= ĠNamed Tracing Process Reader . for Standard Error ( proc Start Result , Ġprocess ID , Ġconfig . encoding ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġout Ġ= ĠNamed Tracing Process Reader . for Standard Output ( proc Start Result , Ġprocess ID , Ġconfig . encoding ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġin lined Ġcopy - past a Ġfrom ĠCor outine Start . start ... Ċ // ĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcontinuation Ġ= Ġbody . create Coroutine Un intercept ed ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmake Coroutine ( sus pension G apped Function Ġ= Ġ:: read To Prob able Close , Ġcontext Ġ= Ġcoroutine Context , Ġpipe Output To Ġ= Ġthis :: resume ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. try C ancell ably Invoke ( finally Ġ= Ġthis :: resume With Exception ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠIOException Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess State . update AndGet Ġ{ Ġstate Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( state ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> ĠTODO (" state =$ newState ĠonStart () ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning , Ġis ĠBe ing K illed Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnote : Ġif Ġwe Ġgot Ġkilled Ġbefore Ġthis , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠClosed ( Process Closing . Not Started ( proc Start Result )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported , Ġis ĠClosed Ġ-> ĠTODO (" state =$ newState ĠonStart () ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġfailed Ġto Ġstart Ġthe Ġsub - process Ġbut Ġwe 're Ġalready Ġrunning ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis . resume ( K illed Before Started ExitCode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠClosed Ġ-> Ġthis . resume ( newState . closed Output . exit Code ) Ġ// Ġkill () Ġbefore Ġstart () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported , Ġis ĠBe ing K illed , Ġis ĠNot Started Ġ-> ĠTODO (" state =$ newState ĠonStart () ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġthis Ġmethod Ġcan Ġmiss Ġoutput Ġon Ġwin 3 2 Ġbecause Ġof Ġattach To Console , ĊĠĠĠ Ġ// Ġif Ġa Ġchild Ġprocess Ġatt aches Ġto Ġthe Ġsame Ġconsole Ġas Ġwe 're Ġreading Ġfrom Ġwe ĊĠĠĠ Ġ// Ġw ont Ġget Ġa Ġclear ĠEOF Ġsignal Ġon Ġthe Ġstandard Ġoutput , Ġso ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġread To Prob able Close (): ĠInt Ġ= Ġdo Tracing (" body . invoke () ") Ġ{ Ġtracing Ġ-> ĊĊĠĠĠĠĠĠĠ Ġ// ĠExec Coroutine Ġdoes Ġsupport Ġcancellation ĊĠĠĠĠĠĠĠ Ġ// Ġbut Ġit Ġis Ġimplemented Ġentirely Ġvia Ġkill (), ĊĠĠĠĠĠĠĠ Ġ// Ġregardless Ġof Ġwhether Ġor Ġnot Ġwe Ġare Ġcancelled Ġthis Ġfunction ĊĠĠĠĠĠĠĠ Ġ// Ġmust Ġread Ġoutput Ġuntil Ġit Ġis Ġclosed . ĊĠĠĠĠĠĠĠ Ġ// ĠTODO : Ġis Ġit Ġpossible Ġfor Ġ' kill Ġ- 9 ' ĠOR Ġ' task kill Ġ/ force ' Ġto Ġfail ? ĊĠĠĠĠĠĠĠ Ġwith Context ( Non C ancellable ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġpol led State Ġ= Ġprocess State . get () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// note : Ġwe Ġmay Ġalready Ġbe Ġin Ġthe Ġfinal Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġif Ġthere Ġis Ġcontent ion Ġbetween Ġcoroutine . start () Ġand Ġkill () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġbackoff Ġ= ĠBack off Window Millis . first ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhile Ġ( pol led State Ġis ĠRunning Or Being K illed ) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpol led State . run Ġ{ Ġcheck ( err Open Ġ|| Ġerr Open Ġ|| Ġexit Code OrNull Ġ!= Ġnull ) Ġ{ Ġ" state Ġnot Ġprom oted : Ġ$ this " Ġ} Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Cancelled Ġ&& Ġpol led State Ġis ĠRunning ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkill 0 ( Cancelled ExitCode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( coroutine Context [ Continuation Interceptor ] Ġ== ĠDispatch ers . IO ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġoutputs OrNull Ġ= Ġpoll Outputs AndUpdate State ( pol led State )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbackoff Ġ= Ġ( backoff Ġ* Ġ 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. coerce In ( Backoff Window Millis ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. coerce At Least ( 1 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdelay ( backoff ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfor Ġ( event Ġin Ġoutputs OrNull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput ( event ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpol led State Ġ= Ġprocess State . get () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( val Ġfinish ing State Ġ= Ġpol led State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported Ġ-> Ġfinish ing State . closed Output . exit Code ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠClosed Ġ-> Ġmake Result < Result < Int >>( tracing ). get OrThrow () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed , Ġis ĠNot Started , Ġis ĠRunning Ġ-> ĠTODO (" finish ing State =$ finish ing State Ġin Ġbody . finally ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġack , Ġthis Ġis nt Ġa Ġnice Ġfunction ĊĠĠĠ Ġ// Ġit Ġchanges Ġthe Ġprocess State Ġfield Ġand ĊĠĠĠ Ġ// Ġand Ġmessages . add And Parse () Ġis Ġalso Ġnot Ġref Ġtransparent ĊĠĠĠ Ġ// Ġand Ġmaking Ġthem Ġso Ġrequires Ġmore Ġobject Ġallocations ... Ġdo Ġwe Ġcare ? ĊĠĠĠ Ġ// ĠTODO : Ġmake Ġthis Ġmore Ġref Ġtransparent Ġ-- maybe Ġadd Ġsupport Ġfor Ġbinary ĠIO ĊĠĠĠ Ġ// Ġthe Ġupdate State Ġportion Ġof Ġthis Ġis Ġtricky Ġsince Ġits Ġa ĠC AS ... ĊĠĠĠ Ġ// Ġpl enty Ġof Ġs oph istic ated Ġconcepts Ġfor Ġa ĠC AS Ġloop Ġaround ... ĊĠĠĠ Ġ// Ġcan ĠI Ġmake Ġthis Ġmore Ġid iom atic ? ĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġpoll Outputs AndUpdate State ( initialState : ĠRunning Or Being K illed ): ĠList < Process Event >? Ġ{ ĊĊĠĠĠĠĠĠĠ Ġ@ Suppress (" Blocking Method In Non Blocking Context ") Ġval Ġerr Ready Ġ= Ġerr . ready () ĊĠĠĠĠĠĠĠ Ġ@ Suppress (" Blocking Method In Non Blocking Context ") Ġval Ġout Ready Ġ= Ġout . ready () ĊĠĠĠĠĠĠĠ Ġval Ġexit Code Ready Ġ= Ġ! handle . is Alive ĊĊĠĠĠĠĠĠĠ Ġval Ġprocess Ended Ġ= ĠinitialState . exit Code OrNull Ġ!= Ġnull ĊĊĠĠĠĠĠĠĠ Ġval Ġoutputs OrNull : ĠList < Process Event >? Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġread Ġerr Ġprefer entially , Ġsince Ġwhen Ġthe Ġexit Ġcode Ġis nt Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe 're Ġgoing Ġto Ġsl am Ġthis Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState . err Open Ġ&& Ġ( err Ready Ġ|| Ġprocess Ended ) Ġ-> Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchunk Ġ= Ġerr . read Available ( force Ġ= Ġprocess Ended ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( chunk Ġ=== ĠEND _ OF _ FILE _ CHUNK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess State . update AndGet Ġ{ Ġstate Ġ-> Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġclosed Or Prom oted ( state , Ġerr Now Open Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed Ġ-> Ġclosed Or Prom oted ( state , Ġerr Now Open Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported , Ġis ĠClosed Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List < Process Event >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnote : Ġwe Ġdont Ġneed Ġsome Ġkind Ġof ĠC AS Ġloop Ġon Ġreading Ġthis Ġfragment ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġsince Ġonly Ġwe Ġcan Ġread Ġoutput Ġfrom Ġthe Ġstream , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġso Ġif Ġwe Ġget Ġoutput , Ġeven Ġif Ġit Ġwas Ġclosed Ġby Ġsom body Ġelse , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġit 's Ġstill Ġsafe Ġto Ġbo unce Ġto Ġthe Ġoutput Ġstream ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlines Ġ= Ġerr Messages . add And Parse ( chunk !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrecent Errors Ġ+= Ġlines ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlines . map (:: Standard ErrorMessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState . out Open Ġ&& Ġ( out Ready Ġ|| Ġprocess Ended ) Ġ-> Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġchunk Ġ= Ġout . read Available ( force Ġ= Ġprocess Ended ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( chunk Ġ=== ĠEND _ OF _ FILE _ CHUNK ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess State . update AndGet Ġ{ Ġstate Ġ-> Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġclosed Or Prom oted ( state , Ġout Now Open Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed Ġ-> Ġclosed Or Prom oted ( state , Ġout Now Open Ġ= Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported , Ġis ĠClosed Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġempty List < Process Event >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġout Messages ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. add And Parse ( chunk !! ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map (:: Standard Output Message ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠinitialState . exit Code OrNull Ġ== Ġnull Ġ&& Ġexit Code Ready Ġ-> Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexit Code Ġ= Ġprocess . exit Value () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprior State Ġ= Ġprocess State . get AndUpdate Ġ{ Ġstate Ġ-> Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġclosed Or Prom oted ( state , Ġnew ExitCode OrNull Ġ= Ġexit Code ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed Ġ-> Ġclosed Or Prom oted ( state , Ġnew ExitCode OrNull Ġ= Ġexit Code ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported , Ġis ĠClosed Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( prior State Ġis ĠRunning Or Being K illed Ġ&& Ġprior State . exit Code OrNull Ġ== Ġnull ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcode Ġ= Ġwhen Ġ( prior State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġexit Code ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed Ġ-> Ġprior State . closed Output . exit Code ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported , Ġis ĠClosed Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠlistOf ( ExitCode ( code )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġoutputs OrNull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġoutput ( it : ĠProcess Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsent Ġ= Ġchannel . try Send ( it ) ĊĊĠĠĠĠĠĠĠ Ġif ( sent . is Failure ) Ġtracing . trace Ġ{ Ġ" failed Ġto Ġsend Ġ'$ it ' Ġ! ?" Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon C ancell ing ( cause : ĠThrowable ?) Ġ= Ġdo Tracing (" on C ancell ing ($ cause )") { Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġ// Ġnoop ? ĊĠĠĠĠĠĠĠ Ġval Ġx Ġ= Ġ 4 ; ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Cancelled ( cause : ĠThrowable , Ġhandled : ĠBoolean ) Ġ= Ġdo Tracing (" on Cancelled ($ cause )") { Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġprevious State Ġ= Ġprocess State . get AndUpdate Ġ{ Ġstate Ġ-> Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġhappens Ġwhen Ġa Ġlazy Ġcoroutine Ġis Ġcreated Ġand Ġthen Ġthe Ġparent Ġis Ġkilled ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠClosed ( Process Closing . K illed ( null , Ġmake Process K illed Exception ( tracing , Ġnull ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( cause Ġis ĠIOException ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠClosed ( Process Closing . Not Started ( cause )) Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTODO (" state =$ state Ġin Ġon Cancelled ($ cause )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed Ġ-> ĠTODO (" state =$ state Ġin Ġon Cancelled ($ cause )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported Ġ-> ĠClosed ( state . closed Output ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠClosed Ġ-> Ġstate . also Ġ{ Ġtracing . trace Ġ{ Ġ" on Cancelled Ġwhen Ġsome body Ġclosed ?" Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ}} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( previous State Ġ! is ĠClosed ) Ġcommit Close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Completed ( value : ĠInt ?) Ġ= Ġdo Tracing (" on Completed ($ value )") { Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġprevious State Ġ= Ġprocess State . get AndUpdate Ġ{ Ġstate Ġ-> Ġwhen Ġ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started , Ġis ĠRunning , Ġis ĠBe ing K illed Ġ-> ĠTODO (" state =$ state Ġin Ġon Completed ($ value )") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported Ġ-> ĠClosed ( state . closed Output ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠClosed Ġ-> Ġstate . also Ġ{ Ġtracing . trace Ġ{ Ġ" onComplete Ġwhen Ġsome body Ġclosed ?" Ġ} Ġ} ĊĠĠĠĠĠĠĠ Ġ}} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( previous State Ġ! is ĠClosed ) Ġcommit Close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġthis Ġmethod Ġis Ġtricky , ĊĠĠĠ Ġ// Ġwhen Ġwe Ġcomplete Ġnormally , Ġon Completed () Ġwill Ġbe Ġsufficient ĊĠĠĠ Ġ// Ġbut Ġin Ġthe Ġcase Ġof Ġcancellation , Ġclosing - up Ġin Ġon Cancel () Ġis Ġtoo Ġeager ĊĠĠĠ Ġ// Ġsince Ġthe Ġprocess Ġwill Ġproduce Ġmore Ġoutput . ĊĠĠĠ Ġ// Ġso Ġthe Ġstrategy Ġis Ġthis : Ġthe Ġgu y Ġwho Ġdoes Ġa Ġstate Ġtransfer Ġto ĠClosed () Ġis Ġresponsible Ġfor Ġcalling Ġthis . ĊĠĠĠ Ġprivate Ġfun Ġcommit Close () Ġ= Ġdo Tracing (" commit Close "){ Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġprocess State . get () ĊĠĠĠĠĠĠĠ Ġcheck ( state Ġis ĠClosed ) ĊĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġmake Result < Result < Int >>( tracing ) ĊĠĠĠĠĠĠĠ Ġif ( result . is Success ) Ġchannel . close () Ġelse Ġchannel . close ( result . exception OrNull () !! ) ĊĠĠĠ Ġ} Ċ Ċ // ĠĠĠ Ġprivate Ġfun Ġmake Result (): ĠResult < Int > Ġ{ Ġ-- Ġfails Ġfor ĠABI Ġstability ... Ġe hh hh .... ĊĠĠĠ Ġ@ Suppress (" FINAL _ UPPER _ BOUND ") Ġ// Ġusing Ġgeneric Ġto Ġdod ge Ġkotlin c Ġedge Ġcase Ġ" dont Ġuse ĠResult Ġas Ġreturn Ġvalue " ĊĠĠĠ Ġprivate Ġfun Ġ< T : ĠResult < Int >> Ġmake Result ( tracing : ĠCor outine Tracer ): ĠT Ġ/* kotlin . Result < Int > */ Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstate Ġ= Ġ( process State . get () Ġas ĠClosed ) ĊĊĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") Ġreturn Ġwhen ( val Ġoutput Ġ= Ġstate . closed Output ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠProcess Closing . Completed Norm ally Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . exit Code . take If Ġ{ Ġconfig . expected Exit Codes Ġ== Ġnull Ġ|| Ġit Ġin Ġconfig . expected Exit Codes !! Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠResult . success ( output . exit Code ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠResult . failure ( make Invalid ExitCode Exception ( tracing , Ġoutput . exit Code )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠProcess Closing . K illed Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoutput . ob tr ude ExitCode . take If Ġ{ Ġconfig . expected Exit Codes Ġ== Ġnull Ġ|| Ġit Ġin Ġconfig . expected Exit Codes !! Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĠResult . success ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠResult . failure ( output . kill Source ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠProcess Closing . Cancelled And K illed Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠResult . failure ( make Cancelled Exception ( tracing , Ġoutput . c ancell ing Ex )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠProcess Closing . Not Started Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen ( val Ġex Ġ= Ġoutput . proc Start Exception ){ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠThrowable Ġ-> ĠResult . failure ( make Process Failed To Start Exception ( tracing , Ġoutput . proc Start Exception )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnull Ġ-> ĠResult . success ( output . exit Code ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠTODO ("$ ex Ġnot Ġthrowable Ġnor Ġnull ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġas ĠT ĊĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ// ĠTODO : Ġsupport Ġfor Ġbinary Ġinput Ġand Ġoutput . ĊĠĠĠ Ġoverride Ġfun Ġsend Line ( input : ĠString ): ĠUnit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġencoded Ġ= Ġ( input Ġ+ Ġ'\ n '). toByteArray ( config . encoding ) ĊĠĠĠĠĠĠĠ Ġstart () ĊĠĠĠĠĠĠĠ Ġprocess . output Stream . run Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġwrite ( encoded ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġflush () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġkill ( ob tr ude ExitCode : ĠInt ?): ĠUnit Ġ{ ĊĠĠĠĠĠĠĠ Ġrequire ( ob tr ude ExitCode Ġ== Ġnull Ġ|| Ġob tr ude ExitCode Ġ>= Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġkill 0 ( ob tr ude ExitCode ) ĊĠĠĠĠĠĠĠ Ġjoin () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġkill 0 ( ob tr uding ExitCode Or Kill Code : ĠInt ?): ĠUnit Ġ= Ġdo Tracing (" kill 0 ( ob tr ude =$ ob tr uding ExitCode Or Kill Code )", Ġmark Ġ= Ġtrue ){ Ġtracing Ġ-> ĊĊĠĠĠĠĠĠĠ Ġval Ġclosed Output : ĠProcess Closing Ġ= Ġwhen ( ob tr uding ExitCode Or Kill Code ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull , Ġin Ġ 0 Ġ.. ĠInt . MAX _ VALUE Ġ-> ĠProcess Closing . K illed ( ob tr uding ExitCode Or Kill Code , Ġmake Process K illed Exception ( tracing , Ġob tr uding ExitCode Or Kill Code )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠK illed Before Started ExitCode Ġ-> ĠProcess Closing . K illed ( K illed Before Started ExitCode , Ġmake Process K illed Exception ( tracing , Ġob tr uding ExitCode Or Kill Code )) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠCancel led ExitCode Ġ-> ĠProcess Closing . Cancelled And K illed ( make Process K illed Exception ( tracing , Ġob tr uding ExitCode Or Kill Code , Ġget Cancellation Exception ())) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" unknown Ġob tr ude ExitCode Ġ$ ob tr uding ExitCode Or Kill Code ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġis C ancell ing Ġ= Ġob tr uding ExitCode Or Kill Code Ġ== ĠCancel led ExitCode ĊĊĠĠĠĠĠĠĠ Ġval Ġprior State Ġ= Ġprocess State . get AndUpdate Ġ{ Ġstate Ġ-> Ġwhen ( state ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> ĠClosed ( Process Closing . Not Started ( null )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġkilled ( state , Ġclosed Output ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif ( is C ancell ing ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate . copy ( closed Output ) Ġ/* we Ġ' upgrade ' Ġfrom Ġa Ġkill Ġto Ġa Ġcancel */ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is C ancell ing ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠAll Outputs Reported ( closed Output ) Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstate Ġ// Ġnoop Ġsince Ġwe Ġtried Ġto Ġkill Ġa Ġfinished Ġprocess Ġ-- let Ġit Ġfinish Ġnormally ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠClosed Ġ-> Ġstate Ġ// Ġprocess Ġalready Ġfinished Ġand Ġreported Ġ-- this Ġmight Ġbe Ġa Ġuser Ġerror ? ĊĠĠĠĠĠĠĠ Ġ}} ĊĊĠĠĠĠĠĠĠ Ġwhen Ġ( prior State ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠNot Started Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġprocess Ġnever Ġstarted , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( process State . get () Ġis ĠClosed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Close () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠRunning Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe Ġgot Ġthe Ġkill , Ġso Ġnow Ġwe Ġactually Ġhave Ġto Ġdo Ġit ! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcommit Kill Async () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠBe ing K illed Ġ-> ĠUnit Ġ// Ġcontent ion : Ġthe Ġprocess Ġwas Ġkilled Ġby Ġsome body Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠAll Outputs Reported Ġ-> ĠUnit Ġ// Ġcontent ion : Ġtried Ġkilled Ġa Ġprocess Ġthat s Ġalready Ġfinished ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠClosed Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcheck (! is C ancell ing ) Ġ// Ġtoo Ġlate Ġto Ġcancel ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġwe 're Ġprotected Ġby Ġcor outines Ġhere , Ġit Ġwill Ġhandle Ġsome body Ġcalling Ġcancel () Ġtwice Ġor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcalling Ġcancel () Ġon Ġa Ġcoroutine Ġwhose ĠonComplete () Ġhas Ġalready Ġgone Ġoff . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġfunction Ġdoes Ġnot Ġprovide Ġa Ġsynchronization Ġmechanism Ġon ĊĠĠĠ Ġ// Ġon Ġthe Ġprocess Ġending ! ĊĠĠĠ Ġprivate Ġfun Ġcommit Kill Async () Ġ{ ĊĠĠĠĠĠĠĠ Ġtracing . trace Ġ{ Ġ" commit Kill Async Ġ${ handle . pid () }" Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġdeadline Ġ= ĠSystem . currentTimeMillis () Ġ+ Ġconfig . grace ful Timeout Millis ĊĊĠĠĠĠĠĠĠ Ġval Ġgrace fully K illed Ġ= Ġconfig . grace ful Timeout Millis Ġ!= Ġ 0 L ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġdo Platform Kill Grace fully And Synchronize ( deadline ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( grace fully K illed ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtracing . trace Ġ{ Ġ" kill Ġgrace fully Ġappears Ġsuccessful " Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠJ EP 1 0 2 Process Facade . kill Force fully Async ( tracing , Ġprocess , Ġconfig . include Desc endants In Kill ) ĊĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġprocess . waitFor () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdo Platform Kill Grace fully And Synchronize ( deadline : ĠLong ): ĠBoolean Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġos Ġ= ĠSystem . getProperty (" os . name "). lowercase () ĊĊĠĠĠĠĠĠĠ Ġval Ġprobably Suc ce ded In Grace full K illing Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" windows " Ġin Ġos Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠWindows Process Control . try Kill Grace fully Async ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtracing , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠProcess Handle . current (). pid (), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconfig . include Desc endants In Kill , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdeadline ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" nix " Ġin Ġos Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠJ EP 1 0 2 Process Facade . try Kill Grace fully Async ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtracing , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġprocess , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconfig . include Desc endants In Kill , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdeadline ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠTODO (" unknown ĠOS : Ġ$ os ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtimeout Ġ= Ġdeadline Ġ- ĠSystem . currentTimeMillis () ĊĠĠĠĠĠĠĠ Ġif ( timeout Ġ<= Ġ 0 ) Ġreturn Ġfalse . also Ġ{ Ġtracing . trace Ġ{ Ġ" timed Ġout " Ġ}} ĊĊĠĠĠĠĠĠĠ Ġprocess . output Stream . close () ĊĊĠĠĠĠĠĠĠ Ġval Ġdead Ġ= Ġprobably Suc ce ded In Grace full K illing ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ&& Ġprocess . waitFor ( timeout , ĠTimeUnit . MILLISECONDS ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġdead ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// Ġnote : ĠI Ġdont Ġhave Ġaccess Ġto Ġawait Internal () Ġon ĠJob Support ĊĠĠĠ Ġ// Ġwhich Ġis Ġwhat ĠDeferred Coroutine Ġuses . ĊĠĠĠ Ġ// Ġso Ġwe Ġsynchronize Ġwith Ġjoin () Ġand Ġfetch Ġthe Ġresult Ġwith Ġour Ġown Ġstate . ĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġawait (): ĠInt ? Ġ= Ġdo Tracing (" await ", Ġmark Ġ= Ġtrue ){ Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġjoin () ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġmake Result < Result < Int >>( tracing ) ĊĠĠĠĠĠĠĠ Ġreturn Ġresult . get OrThrow (). take If Ġ{ Ġit Ġ>= Ġ 0 Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġon Await : ĠSelect Clause 1 < Int ?> Ġget () Ġ= Ġobject : ĠSelect Clause 1 < Int ? >{ ĊĠĠĠĠĠĠĠ Ġval Ġdelegate : ĠSelect Clause 0 Ġ= Ġon Join ĊĠĠĠĠĠĠĠ Ġ@ Internal Cor outines Api ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġ< R > Ġregister Select Clause 1 ( select : ĠSelect Instance < R >, Ġblock : Ġsuspend Ġ( Int ?) Ġ-> ĠR ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdelegate . register Select Clause 0 ( select ) Ġ{ Ġblock ( await ()) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmake Process Failed To Start Exception ( tracing : ĠCor outine Tracer , Ġproc Start Exception : ĠIOException ): ĠIOException Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠIOException ( proc Start Exception . message ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstack Trace Ġ= Ġtracing . make M angled Trace (). to Typed Array () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmake Cancelled Exception ( tracing : ĠCor outine Tracer , Ġcancell ing Ex : ĠThrowable ) Ġ= ĊĠĠĠĠĠĠĠ ĠC ancellation Exception (" Process Ġwas Ġcancelled Ġ( and Ġkilled )", Ġcancell ing Ex ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstack Trace Ġ= Ġtracing . make M angled Trace (). to Typed Array () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmake Process K illed Exception ( ĊĠĠĠĠĠĠĠ Ġtracing : ĠCor outine Tracer , ĊĠĠĠĠĠĠĠ Ġexit Code : ĠInt ?, ĊĠĠĠĠĠĠĠ Ġsource Exception : ĠException ? Ġ= Ġnull ĊĠĠĠ Ġ): ĠProcess K illed Exception Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġbuild String Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġappend (" k illed Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( exit Code Ġ!= Ġnull ) Ġappend ("( with Ġexit Ġcode Ġ$ exit Code ) Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġappend Abbre vi ated CommandLine () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠProcess K illed Exception ( message , Ġsource Exception ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstack Trace Ġ= Ġtracing . make M angled Trace (). to Typed Array () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġmake Invalid ExitCode Exception ( ĊĠĠĠĠĠĠĠ Ġtracing : ĠCor outine Tracer , ĊĠĠĠĠĠĠĠ Ġexit Code : ĠInt ĊĠĠĠ Ġ): ĠInvalid ExitCode Exception Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġrecent Error Lines Ġ= Ġrecent Errors . toList () ĊĊĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġbuild String Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġappend (" exit Ġcode Ġ$ exit Code Ġfrom Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġappend Abbre vi ated CommandLine () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( recent Error Lines . any ()) Ġappend Line (). append Line (" the Ġmost Ġrecent Ġstandard - error Ġoutput Ġwas :") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( recent Error Line Ġin Ġrecent Error Lines ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġappend Line ( recent Error Line . take ( Column Limit )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn ĠInvalid ExitCode Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexit Code , Ġconfig . expected Exit Codes , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġconfig . command , Ġrecent Error Lines , Ġmessage ĊĠĠĠĠĠĠĠ Ġ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstack Trace Ġ= Ġtracing . make M angled Trace (). to Typed Array () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠStringBuilder . append Abbre vi ated CommandLine () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcmd Line Ġ= Ġconfig . command . join ToString (" Ġ") ĊĠĠĠĠĠĠĠ Ġappend ( cmd Line . take ( Column Limit )) ĊĠĠĠĠĠĠĠ Ġif Ġ( cmd Line . length Ġ> ĠColumn Limit ) Ġappend ("[ ... ]") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġreceive (): ĠProcess Event Ġ= Ġdo Tracing (" receive ", Ġmark Ġ= Ġtrue ){ Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġchannel . receive () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcatch ( ex : ĠC ancellation Exception ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġmake Cancelled Exception ( tracing , Ġex ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġon Receive : ĠSelect Clause 1 < Process Event > ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġchannel . on Receive ĊĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġreceive Catch ing (): ĠChannel Result < Process Event > Ġ= Ġdo Tracing (" receive Catch ing ", Ġtrue ){ Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġchannel . receive Catch ing () ĊĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . is Success Ġ-> Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . is Closed Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsource Ex Ġ= Ġresult . exception OrNull () Ġas ? ĠC ancellation Exception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: ĠC ancellation Exception (" Cancellation Ġwhile Ġreceiving ", Ġresult . exception OrNull ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠChannel Result . closed ( make Cancelled Exception ( tracing , Ġsource Ex )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . is Failure Ġ-> Ġresult ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> ĠTODO () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġval Ġon Receive Catch ing : ĠSelect Clause 1 < Channel Result < Process Event >> ĊĠĠĠĠĠĠĠ Ġget () Ġ= Ġchannel . on Receive Catch ing ĊĊĠĠĠ Ġoverride Ġfun Ġtry Receive (): ĠChannel Result < Process Event > Ġ= Ġchannel . try Receive () ĊĊĠĠĠ Ġ@ Opt In ( Internal Cor outines Api :: class ) ĊĠĠĠ Ġoverride Ġsuspend Ġfun Ġcollect ( collector : ĠFlow Collector < Process Event >) Ġ= Ġdo Tracing (" collect ", Ġmark Ġ= Ġtrue ) Ġ{ Ġtracing Ġ-> ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdo Ġwe Ġconvert Ġchannel Ġto Ġflow Ġahead Ġof Ġtime Ġonce Ġor Ġdo Ġwe Ġdo Ġit Ġper Ġrequest ? ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġim Ġdoing Ġthe Ġlatter Ġbecause Ġit Ġthrows - away Ġaborted Ġflows ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ( calling Ġfirst () Ġwill Ġabort Ġthe Ġflow , Ġbut ĠI Ġdo Ġnot Ġwant Ġthat Ġto Ġprevent Ġfuture Ġoutput ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġflow Ġ= Ġchannel . receive As Flow () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġflow . collect ( collector ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcatch ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġif ( ex Ġis ĠC ancellation Exception ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġex Ġelse Ġ// abort Ġflow Ġexception Ġmust Ġbe Ġthrown Ġas - is ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠC ancellation Exception (" Process Ġa br upt ly Ġstopped Ġproducing Ġoutput ", Ġex ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġstack Trace Ġ= Ġtracing . make M angled Trace (). to Typed Array () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinline Ġfun Ġ< R > Ġdo Tracing ( block Name : ĠString , Ġmark : ĠBoolean Ġ= Ġfalse , Ġblock : Ġ( Coroutine Tracer ) Ġ-> ĠR ): ĠR { ĊĠĠĠĠĠĠĠ Ġval Ġinitial Tracing Ġ= Ġtracing ĊĠĠĠĠĠĠĠ Ġval Ġtracing Ġ= Ġif ( mark ) Ġinitial Tracing . mark ( block Name ) Ġelse Ġinitial Tracing ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtracing . trace Ġ{ Ġ"${ process State . get ()} Ġ-> Ġ$ block Name " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġblock ( tracing ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġcatch ( ex : ĠThrowable ){ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Tracing . trace ( is Err Ġ= Ġtrue ) Ġ{ Ġ"$ block Name Ġthrew / will Ġthrow Ġ$ ex " Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinitial Tracing . trace Ġ{ Ġ"$ block Name Ġ-> Ġ${ process State . get () }" Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġkilled ( state : ĠRunning , Ġclosed Output : ĠProcess Closing ) Ġ= ĠBe ing K illed ( ĊĠĠĠ Ġstate . err Open , ĊĠĠĠ Ġstate . out Open , ĊĠĠĠ Ġstate . exit Code OrNull , ĊĠĠĠ Ġclosed Output Ċ ) Ċ Ċ private Ġfun Ġclosed Or Prom oted ( ĊĠĠĠ Ġstate : ĠRunning Or Being K illed , ĊĠĠĠ Ġerr Now Open : ĠBoolean Ġ= Ġstate . err Open , ĊĠĠĠ Ġout Now Open : ĠBoolean Ġ= Ġstate . out Open , ĊĠĠĠ Ġnew ExitCode OrNull : ĠInt ? Ġ= Ġstate . exit Code OrNull Ċ ): ĠState Ġ{ ĊĠĠĠ Ġval Ġexit Code OrNull Ġ= Ġstate . exit Code OrNull Ġ?: Ġnew ExitCode OrNull ĊĠĠĠ Ġval Ġis Finished Ġ= Ġ! err Now Open Ġ&& Ġ! out Now Open Ġ&& Ġexit Code OrNull Ġ!= Ġnull ĊĊĠĠĠ Ġval Ġresult Ġ= Ġwhen Ġ{ ĊĠĠĠĠĠĠĠ Ġstate Ġis ĠRunning Ġ&& Ġ! Ġis Finished Ġ-> ĠRunning ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerr Open Ġ= Ġerr Now Open , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout Open Ġ= Ġout Now Open , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexit Code OrNull Ġ= Ġexit Code OrNull ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġstate Ġis ĠRunning Ġ&& Ġis Finished Ġ-> ĠAll Outputs Reported ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠProcess Closing . Completed Norm ally ( new ExitCode OrNull !! ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġstate Ġis ĠBe ing K illed Ġ Ġ&& Ġ! Ġis Finished Ġ-> ĠBe ing K illed ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġerr Open Ġ= Ġerr Now Open , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout Open Ġ= Ġout Now Open , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexit Code OrNull Ġ= Ġexit Code OrNull , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate . closed Output ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġstate Ġis ĠBe ing K illed Ġ&& Ġis Finished Ġ-> ĠAll Outputs Reported ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstate . closed Output ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĠTODO (" cant Ġclose Ġor Ġpromote Ġ$ state ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġrequire ( state Ġ!= Ġresult ) Ġ{ Ġ" did nt Ġclose Ġand Ġdid nt Ġpromote , Ġbefore =$ state , Ġafter =$ result " Ġ} ĊĊĠĠĠ Ġreturn Ġresult Ċ } Ċ Ċ private Ġsealed Ġclass ĠState Ġ{ ĊĠĠĠ Ġopen Ġoverride Ġfun ĠtoString (): ĠString Ġ= Ġthis :: class . simple Name Ġ?: Ġ" anon " Ċ } Ċ private Ġobject ĠNot Started : ĠState () Ċ interface ĠRunning Or Being K illed Ġ{ ĊĠĠĠ Ġval Ġerr Open : ĠBoolean ĊĠĠĠ Ġval Ġout Open : ĠBoolean ĊĠĠĠ Ġval Ġexit Code OrNull : ĠInt ? Ċ } Ċ private Ġclass ĠRunning ( ĊĠĠĠ Ġoverride Ġval Ġerr Open : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġoverride Ġval Ġout Open : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġoverride Ġval Ġexit Code OrNull : ĠInt ? Ġ= Ġnull Ċ ): ĠState (), ĠRunning Or Being K illed Ċ Ċ private Ġclass ĠBe ing K illed ( ĊĠĠĠ Ġoverride Ġval Ġerr Open : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġoverride Ġval Ġout Open : ĠBoolean Ġ= Ġtrue , ĊĠĠĠ Ġoverride Ġval Ġexit Code OrNull : ĠInt ? Ġ= Ġnull , ĊĠĠĠ Ġval Ġclosed Output : ĠProcess Closing Ċ ): ĠState (), ĠRunning Or Being K illed Ġ{ ĊĠĠĠ Ġfun Ġcopy ( new Closed Output : ĠProcess Closing ) Ġ= ĠBe ing K illed ( err Open , Ġout Open , Ġexit Code OrNull , Ġnew Closed Output ) Ċ } Ċ Ċ sealed Ġclass ĠProcess Closing () Ġ{ ĊĊĠĠĠ Ġabstract Ġval Ġexit Code : ĠInt ĊĊĠĠĠ Ġclass ĠNot Started ( val Ġproc Start Exception : ĠIOException ?): ĠProcess Closing (){ ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġexit Code : ĠInt Ġget () Ġ= ĠK illed Before Started ExitCode ĊĠĠĠ Ġ} ĊĠĠĠ Ġclass ĠCompleted Norm ally ( override Ġval Ġexit Code : ĠInt ): ĠProcess Closing () ĊĠĠĠ Ġclass ĠK illed ( val Ġob tr ude ExitCode : ĠInt ?, Ġval Ġkill Source : ĠProcess K illed Exception ): ĠProcess Closing () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġexit Code Ġget () Ġ= Ġob tr ude ExitCode Ġ?: ĠK illed Without Ob tr uding Code ExitCode ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// Ġdifference Ġhere Ġis Ġthat Ġwe Ġkill Ġthe Ġsub - process Ġbut Ġalso Ġact Ġwith Ġcancellation Ġsemantics ĊĠĠĠ Ġ// Ġresult - ish Ġthings Ġ( collect , Ġawait , Ġetc ) Ġmust Ġthrow Ġa ĠC ancellation Exception Ġinstead Ġof ĊĠĠĠ Ġ// Ġthe Ġtypical Ġkill Ġbehaviour ĊĠĠĠ Ġclass ĠCancel led And K illed ( val Ġcancell ing Ex : ĠProcess K illed Exception ): ĠProcess Closing () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġval Ġexit Code Ġget () Ġ= ĠCancel led ExitCode ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġclass ĠAll Outputs Reported ( val Ġclosed Output : ĠProcess Closing ): ĠState () Ċ private Ġclass ĠClosed ( val Ġclosed Output : ĠProcess Closing ): ĠState () Ċ Ċ val ĠBack off Window Millis Ġ= Ġ 0 L Ġ.. Ġ 1 0 0 L Ċ val ĠEND _ OF _ FILE _ CHUNK : ĠChar Array ? Ġ= Ġnull Ċ Ċ val ĠK illed Before Started ExitCode Ġ= Ġ- 1 Ċ val ĠCancel led ExitCode Ġ= Ġ- 2 Ċ val ĠK illed Without Ob tr uding Code ExitCode Ġ= Ġ- 5 Ċ val ĠColumn Limit Ġ= Ġ 5 1 2 Ċ Ċ // Ġhelper Ġto Ġforce Ġthe Ġruntime Ġto Ġstop Ġoptim izing Ġthings Ċ // Ġso Ġa Ġdebugger Ġcan Ġactually Ġsee Ġwhat Ġis Ġhappening Ċ internal Ġfun Ġdo Stuff ( var arg Ġany : ĠAny ? ){ ĊĠĠĠ Ġval Ġx Ġ= Ġ 4 ; Ċ }