55use Amp \ByteStream \ReadableResourceStream ;
66use Amp \ByteStream \WritableResourceStream ;
77use Amp \Cancellation ;
8+ use Amp \CancelledException ;
89use Amp \ForbidCloning ;
910use Amp \ForbidSerialization ;
1011use Amp \Process \Internal \ProcessStatus ;
1112use Amp \Process \Internal \ProcessStreams ;
1213use Amp \Process \ProcessException ;
14+ use Amp \TimeoutCancellation ;
1315use Revolt \EventLoop ;
1416use function Amp \async ;
1517
@@ -70,7 +72,7 @@ public function connectPipes(WindowsHandle $handle, Cancellation $cancellation):
7072 $ handle ->startBarrier ->await ($ cancellation );
7173
7274 $ controlPipe = new ReadableResourceStream ($ handle ->sockets [0 ]);
73- $ handle ->pid = $ this ->readChildPid ($ controlPipe );
75+ $ handle ->pid = $ this ->readChildPid ($ controlPipe, $ cancellation );
7476 } catch (\Throwable $ exception ) {
7577 foreach ($ handle ->sockets as $ socket ) {
7678 \fclose ($ socket );
@@ -97,9 +99,9 @@ public function connectPipes(WindowsHandle $handle, Cancellation $cancellation):
9799 $ handle ->exitCodeStream = $ controlPipe ;
98100
99101 $ stdin = \WeakReference::create ($ streams ->stdin );
100- async (function () use ($ handle , $ stdin) {
102+ async (function () use ($ handle , $ stdin, $ cancellation ): void {
101103 try {
102- $ exitCode = $ this ->readExitCode ($ handle ->exitCodeStream );
104+ $ exitCode = $ this ->readExitCode ($ handle ->exitCodeStream , $ cancellation );
103105
104106 $ handle ->joinDeferred ->complete ($ exitCode );
105107 } catch (\Throwable ) {
@@ -128,11 +130,11 @@ private function acceptClient(): void
128130 throw new \Error ("Failed to set client socket to non-blocking mode " );
129131 }
130132
131- async (function () use ($ socket ) {
133+ async (function () use ($ socket ): void {
132134 try {
133- $ handle = $ this ->performClientHandshake ($ socket );
135+ $ handle = $ this ->performClientHandshake ($ socket, new TimeoutCancellation ( 5 ) );
134136 $ handle ->startBarrier ->arrive ();
135- } catch (HandshakeException $ e ) {
137+ } catch (HandshakeException | CancelledException $ e ) {
136138 /** @psalm-suppress InvalidScalarArgument */
137139 \fwrite ($ socket , \chr (SignalCode::HANDSHAKE_ACK ) . \chr ($ e ->getCode ()));
138140 \fclose ($ socket );
@@ -145,13 +147,13 @@ private function acceptClient(): void
145147 *
146148 * @throws HandshakeException
147149 */
148- public function performClientHandshake ($ socket ): WindowsHandle
150+ public function performClientHandshake ($ socket, Cancellation $ cancellation ): WindowsHandle
149151 {
150152 $ stream = new ReadableResourceStream ($ socket );
151153
152154 $ packet = \unpack (
153155 'Csignal/Npid/Cstream_id/a*client_token ' ,
154- $ this ->read ($ stream , self ::SECURITY_TOKEN_SIZE + 6 )
156+ $ this ->read ($ stream , $ cancellation , length: self ::SECURITY_TOKEN_SIZE + 6 )
155157 );
156158
157159 // validate the client's handshake
@@ -193,7 +195,7 @@ public function performClientHandshake($socket): WindowsHandle
193195 throw new HandshakeException (HandshakeStatus::NO_LONGER_PENDING );
194196 }
195197
196- $ packet = \unpack ('Csignal/Cstatus ' , $ this ->read ($ stream , 2 ));
198+ $ packet = \unpack ('Csignal/Cstatus ' , $ this ->read ($ stream , $ cancellation , length: 2 ));
197199
198200 if ($ packet ['signal ' ] !== SignalCode::HANDSHAKE_ACK || $ packet ['status ' ] !== HandshakeStatus::SUCCESS ) {
199201 throw new HandshakeException (HandshakeStatus::ACK_STATUS_ERROR );
@@ -207,9 +209,9 @@ public function performClientHandshake($socket): WindowsHandle
207209 /**
208210 * @return positive-int
209211 */
210- private function readChildPid (ReadableResourceStream $ stream ): int
212+ private function readChildPid (ReadableResourceStream $ stream, Cancellation $ cancellation ): int
211213 {
212- $ packet = \unpack ('Csignal/Npid ' , $ this ->read ($ stream , 5 ));
214+ $ packet = \unpack ('Csignal/Npid ' , $ this ->read ($ stream , $ cancellation , length: 5 ));
213215 if ($ packet ['signal ' ] !== SignalCode::CHILD_PID ) {
214216 throw new HandshakeException (HandshakeStatus::SIGNAL_UNEXPECTED );
215217 }
@@ -219,9 +221,9 @@ private function readChildPid(ReadableResourceStream $stream): int
219221 return $ pid ;
220222 }
221223
222- private function readExitCode (ReadableResourceStream $ stream ): int
224+ private function readExitCode (ReadableResourceStream $ stream, Cancellation $ cancellation ): int
223225 {
224- $ packet = \unpack ('Csignal/Ncode ' , $ this ->read ($ stream , 5 ));
226+ $ packet = \unpack ('Csignal/Ncode ' , $ this ->read ($ stream , $ cancellation , length: 5 ));
225227
226228 if ($ packet ['signal ' ] !== SignalCode::EXIT_CODE ) {
227229 throw new HandshakeException (HandshakeStatus::SIGNAL_UNEXPECTED );
@@ -230,15 +232,15 @@ private function readExitCode(ReadableResourceStream $stream): int
230232 return (int ) $ packet ['code ' ];
231233 }
232234
233- private function read (ReadableResourceStream $ stream , int $ length ): string
235+ private function read (ReadableResourceStream $ stream , Cancellation $ cancellation , int $ length ): string
234236 {
235237 $ buffer = '' ;
236238
237239 do {
238240 $ remaining = $ length - \strlen ($ buffer );
239241 \assert ($ remaining > 0 );
240242
241- $ chunk = $ stream ->read (limit: $ remaining );
243+ $ chunk = $ stream ->read ($ cancellation , limit: $ remaining );
242244 if ($ chunk === null ) {
243245 break ;
244246 }
0 commit comments