@@ -704,6 +704,10 @@ void *shell_new(t_symbol *s, long ac, t_atom *av)
704
704
// http://rachid.koucha.free.fr/tech_corner/pty_pdip.html
705
705
// using posix_openpt()
706
706
707
+ #ifndef NSIG
708
+ # define NSIG 32
709
+ #endif
710
+
707
711
int shell_pipe_open (t_shell *x, t_fildes *masterfd_r, t_fildes *masterfd_w, char *cmd, char *argv[], t_procid *ppid, int merge_stderr)
708
712
{
709
713
#ifdef MAC_VERSION
@@ -712,7 +716,9 @@ int shell_pipe_open(t_shell *x, t_fildes *masterfd_r, t_fildes *masterfd_w, char
712
716
char *slavedevice;
713
717
int rc;
714
718
char workingdir[MAX_PATH_CHARS] = " " ;
715
-
719
+ sigset_t oldmask, newmask;
720
+ struct sigaction sig_action;
721
+
716
722
*ppid = 0 ;
717
723
718
724
if (masterfd == -1
@@ -740,15 +746,24 @@ int shell_pipe_open(t_shell *x, t_fildes *masterfd_r, t_fildes *masterfd_w, char
740
746
}
741
747
}
742
748
749
+ sigfillset (&newmask);
750
+ if (pthread_sigmask (SIG_SETMASK, &newmask, &oldmask) < 0 ) {
751
+ object_error ((t_object *)x, " error setting sigmask: %s" , strerror (errno));
752
+ return 0 ;
753
+ }
754
+
743
755
*ppid = vfork ();
744
756
if (*ppid < 0 ) {
745
757
close (masterfd);
746
758
close (slavefd);
747
759
return 0 ; // error
748
760
}
761
+
749
762
if (*ppid == 0 ) { // child
750
763
struct termios orig_termios, new_termios;
751
-
764
+
765
+ umask (0 );
766
+
752
767
close (masterfd); // close the master
753
768
754
769
// Save the default parameters of the slave side of the PTY
@@ -770,6 +785,26 @@ int shell_pipe_open(t_shell *x, t_fildes *masterfd_r, t_fildes *masterfd_w, char
770
785
// As the child is a session leader, set the controlling terminal to be the slave side of the PTY
771
786
// (Mandatory for programs like the shell to make them manage correctly their outputs)
772
787
ioctl (0 , TIOCSCTTY, 1 );
788
+
789
+ // reset signals
790
+ sig_action.sa_handler = SIG_DFL;
791
+ sig_action.sa_flags = 0 ;
792
+ sigemptyset (&sig_action.sa_mask );
793
+
794
+ for (int i = 0 ; i < NSIG ; i++) {
795
+ // Only possible errors are EFAULT or EINVAL
796
+ // The former wont happen, the latter we
797
+ // expect, so no need to check return value
798
+ sigaction (i, &sig_action, NULL );
799
+ }
800
+
801
+ // Unmask all signals in child, since we've no idea
802
+ // what the caller's done with their signal mask
803
+ if (pthread_sigmask (SIG_SETMASK, &oldmask, NULL ) < 0 ) {
804
+ object_error ((t_object *)x, " error resetting sigmask (child): %s" , strerror (errno));
805
+ return 0 ;
806
+ }
807
+
773
808
if (*workingdir) {
774
809
chdir (workingdir);
775
810
}
@@ -778,6 +813,11 @@ int shell_pipe_open(t_shell *x, t_fildes *masterfd_r, t_fildes *masterfd_w, char
778
813
} else { // parent
779
814
close (slavefd); // close the slave
780
815
*masterfd_r = *masterfd_w = masterfd;
816
+
817
+ if (pthread_sigmask (SIG_SETMASK, &oldmask, NULL ) < 0 ) {
818
+ object_error ((t_object *)x, " error resetting sigmask: %s" , strerror (errno));
819
+ return masterfd;
820
+ }
781
821
}
782
822
return masterfd;
783
823
#else
0 commit comments