@@ -399,6 +399,7 @@ CAMLprim value spawn_unix(value v_env,
399
399
value v_sigprocmask )
400
400
{
401
401
CAMLparam4 (v_env , v_cwd , v_prog , v_argv );
402
+ CAMLlocal2 (v_sigprocmask_command , v_sigprocmask_signals );
402
403
pid_t ret ;
403
404
struct spawn_info info ;
404
405
int result_pipe [2 ];
@@ -446,6 +447,30 @@ CAMLprim value spawn_unix(value v_env,
446
447
Is_block (v_setpgid ) ?
447
448
Long_val (Field (v_setpgid , 0 )) : 0 ;
448
449
450
+ enum caml_unix_sigprocmask_command sigprocmask_command ;
451
+ int * sigprocmask_signals ; /* array */
452
+ mlsize_t sigprocmask_signals_length ;
453
+
454
+ if (!Is_block (v_sigprocmask )) {
455
+ sigprocmask_command = CAML_SIG_SETMASK ;
456
+ sigprocmask_signals = NULL ;
457
+ sigprocmask_signals_length = 0 ;
458
+ } else {
459
+ v_sigprocmask = Field (v_sigprocmask , 0 );
460
+
461
+ v_sigprocmask_command = Field (v_sigprocmask , 0 );
462
+ v_sigprocmask_signals = Field (v_sigprocmask , 1 );
463
+
464
+ sigprocmask_command = Long_val (v_sigprocmask_command );
465
+ sigprocmask_signals_length = Wosize_val (v_sigprocmask_signals );
466
+ sigprocmask_signals = (int * )malloc (sizeof (int ) * sigprocmask_signals_length );
467
+
468
+ for (mlsize_t i = 0 ; i < sigprocmask_signals_length ; i ++ ) {
469
+ sigprocmask_signals [i ] =
470
+ caml_convert_signal_number (Long_val (Field (v_sigprocmask_signals , i )));
471
+ }
472
+ }
473
+
449
474
caml_enter_blocking_section ();
450
475
enter_safe_pipe_section ();
451
476
@@ -455,6 +480,9 @@ CAMLprim value spawn_unix(value v_env,
455
480
leave_safe_pipe_section ();
456
481
caml_leave_blocking_section ();
457
482
free_spawn_info (& info );
483
+ if (sigprocmask_signals != NULL ) {
484
+ free (sigprocmask_signals );
485
+ }
458
486
unix_error (error , "pipe" , Nothing );
459
487
}
460
488
@@ -478,44 +506,34 @@ CAMLprim value spawn_unix(value v_env,
478
506
sigfillset (& sigset );
479
507
pthread_sigmask (SIG_SETMASK , & sigset , & saved_procmask );
480
508
481
- if (v_sigprocmask == Val_long (0 )) {
482
- sigemptyset (& info .child_sigmask );
483
- } else {
484
- v_sigprocmask = Field (v_sigprocmask , 0 );
485
- value v_sigprocmask_command = Field (v_sigprocmask , 0 );
486
- enum caml_unix_sigprocmask_command sigprocmask_command = Long_val (v_sigprocmask_command );
509
+ switch (sigprocmask_command ) {
510
+ case CAML_SIG_SETMASK :
511
+ sigemptyset (& info .child_sigmask );
512
+ break ;
513
+
514
+ case CAML_SIG_BLOCK :
515
+ case CAML_SIG_UNBLOCK :
516
+ info .child_sigmask = saved_procmask ;
517
+ break ;
487
518
519
+ default :
520
+ caml_failwith ("Unknown sigprocmask action" );
521
+ }
522
+
523
+ for (mlsize_t i = 0 ; i < sigprocmask_signals_length ; i ++ ) {
524
+ int signal = sigprocmask_signals [i ];
488
525
switch (sigprocmask_command ) {
489
526
case CAML_SIG_SETMASK :
490
- sigemptyset (& info .child_sigmask );
527
+ case CAML_SIG_BLOCK :
528
+ sigaddset (& info .child_sigmask , signal );
491
529
break ;
492
530
493
- case CAML_SIG_BLOCK :
494
531
case CAML_SIG_UNBLOCK :
495
- info .child_sigmask = saved_procmask ;
532
+ sigdelset ( & info .child_sigmask , signal ) ;
496
533
break ;
497
534
498
535
default :
499
- caml_failwith ("Unknown sigprocmask action" );
500
- }
501
-
502
- value v_signals_list = Field (v_sigprocmask , 1 );
503
- for (; v_signals_list != Val_emptylist ;
504
- v_signals_list = Field (v_signals_list , 1 )) {
505
- int signal = caml_convert_signal_number (Long_val (Field (v_signals_list , 0 )));
506
- switch (sigprocmask_command ) {
507
- case CAML_SIG_SETMASK :
508
- case CAML_SIG_BLOCK :
509
- sigaddset (& info .child_sigmask , signal );
510
- break ;
511
-
512
- case CAML_SIG_UNBLOCK :
513
- sigdelset (& info .child_sigmask , signal );
514
- break ;
515
-
516
- default :
517
- assert (0 );
518
- }
536
+ assert (0 );
519
537
}
520
538
}
521
539
@@ -529,6 +547,9 @@ CAMLprim value spawn_unix(value v_env,
529
547
530
548
leave_safe_pipe_section ();
531
549
free_spawn_info (& info );
550
+ if (sigprocmask_signals != NULL ) {
551
+ free (sigprocmask_signals );
552
+ }
532
553
close (result_pipe [1 ]);
533
554
534
555
got_error = 0 ;
0 commit comments