@@ -305,6 +305,7 @@ void c_tcp_write(Int handle, struct Pos buffer, Int offset, Int size, Stack stac
305
305
void c_tcp_close_cb (uv_handle_t * handle ) {
306
306
Stack stack = (Stack )handle -> data ;
307
307
free (handle );
308
+ // TODO resume_Pos Unit
308
309
resume_Int (stack , 0 );
309
310
}
310
311
@@ -314,6 +315,102 @@ void c_tcp_close(Int handle, Stack stack) {
314
315
uv_close (uv_handle , c_tcp_close_cb );
315
316
}
316
317
318
+ void c_tcp_listen (String host , Int port , Int backlog , Stack stack ) {
319
+ // TODO make non-async
320
+ char * host_str = c_bytearray_into_nullterminated_string (host );
321
+ erasePositive (host );
322
+
323
+ uv_tcp_t * tcp_handle = malloc (sizeof (uv_tcp_t ));
324
+ int result = uv_tcp_init (uv_default_loop (), tcp_handle );
325
+
326
+ if (result < 0 ) {
327
+ free (tcp_handle );
328
+ free (host_str );
329
+ resume_Int (stack , result );
330
+ return ;
331
+ }
332
+
333
+ struct sockaddr_in addr ;
334
+ result = uv_ip4_addr (host_str , port , & addr );
335
+ free (host_str );
336
+
337
+ if (result < 0 ) {
338
+ free (tcp_handle );
339
+ resume_Int (stack , result );
340
+ return ;
341
+ }
342
+
343
+ result = uv_tcp_bind (tcp_handle , (const struct sockaddr * )& addr , 0 );
344
+ if (result < 0 ) {
345
+ free (tcp_handle );
346
+ resume_Int (stack , result );
347
+ return ;
348
+ }
349
+
350
+ result = uv_listen ((uv_stream_t * )tcp_handle , backlog , NULL );
351
+ if (result < 0 ) {
352
+ free (tcp_handle );
353
+ resume_Int (stack , result );
354
+ return ;
355
+ }
356
+
357
+ resume_Int (stack , (int64_t )tcp_handle );
358
+ }
359
+
360
+ void c_tcp_accept_cb (uv_stream_t * server , int status ) {
361
+ Stack stack = (Stack )server -> data ;
362
+
363
+ if (status < 0 ) {
364
+ resume_Int (stack , status );
365
+ return ;
366
+ }
367
+
368
+ uv_tcp_t * client = malloc (sizeof (uv_tcp_t ));
369
+ int result = uv_tcp_init (uv_default_loop (), client );
370
+
371
+ if (result < 0 ) {
372
+ free (client );
373
+ // TODO share stack?
374
+ resume_Int (stack , result );
375
+ return ;
376
+ }
377
+
378
+ result = uv_accept (server , (uv_stream_t * )client );
379
+ if (result < 0 ) {
380
+ uv_close ((uv_handle_t * )client , NULL );
381
+ free (client );
382
+ // TODO share stack?
383
+ resume_Int (stack , result );
384
+ return ;
385
+ }
386
+
387
+ // TODO share resumption
388
+ // shareStack(stack);
389
+ resume_Int (stack , (int64_t )client );
390
+ }
391
+
392
+ void c_tcp_accept (Int server_handle , Stack stack ) {
393
+ uv_stream_t * server = (uv_stream_t * )server_handle ;
394
+ server -> data = stack ; // Store stack for multiple resumes
395
+
396
+ int result = uv_listen (server , 0 , c_tcp_accept_cb );
397
+ if (result < 0 ) {
398
+ resume_Int (stack , result );
399
+ }
400
+ }
401
+
402
+ void c_tcp_close_listener (Int handle , Stack stack ) {
403
+ uv_handle_t * uv_handle = (uv_handle_t * )handle ;
404
+
405
+ Stack registered_stack = (Stack )uv_handle -> data ;
406
+ if (registered_stack ) {
407
+ eraseStack (registered_stack );
408
+ }
409
+
410
+ uv_handle -> data = stack ;
411
+ uv_close (uv_handle , c_tcp_close_cb );
412
+ }
413
+
317
414
318
415
/**
319
416
* Maps the libuv error code to a stable (platform independent) numeric value.
0 commit comments