]> git.g-eek.se Git - interimap.git/commitdiff
Block SIGINT signals to the children for type=tunnel.
authorGuilhem Moulin <guilhem@fripost.org>
Mon, 7 Sep 2015 22:17:24 +0000 (00:17 +0200)
committerGuilhem Moulin <guilhem@fripost.org>
Mon, 7 Sep 2015 22:19:47 +0000 (00:19 +0200)
So we can clean after us (and for instance remove the lockfile).

INSTALL
interimap
lib/Net/IMAP/InterIMAP.pm

diff --git a/INSTALL b/INSTALL
index e11e08ac587799796b8f71d6e29f646d75ed54ea..7bc3eefb0328a6ca179b6c40c88d8fe189bcec64 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -8,9 +8,8 @@ InterIMAP depends on the following Perl modules:
   - IO::Select (core module)
   - IO::Socket::INET (core module) for 'type=imap'
   - IO::Socket::SSL for 'type=imaps' (or 'type=imap' and 'STARTTLS=YES')
-  - IPC::Open2 (core module) for 'type=tunnel'
   - List::Util (core module)
-  - POSIX (core module) if 'logfile' is set
+  - POSIX (core module)
   - Socket (core module)
   - Time::HiRes (core module) if 'logfile' is set
 
index 6442054bdd0d384e991e674e00e9d5f426cd9943..a94110bca944869e05a83c271456fefee73a0543 100755 (executable)
--- a/interimap
+++ b/interimap
@@ -51,10 +51,12 @@ sub usage(;$) {
     }
     exit $rv;
 }
-usage(1) unless GetOptions(\%CONFIG, qw/config=s quiet|q target=s@ debug help|h repair delete rename/);
+
+my @COMMANDS = qw/repair delete rename/;
+usage(1) unless GetOptions(\%CONFIG, qw/config=s quiet|q target=s@ debug help|h/, @COMMANDS);
 usage(0) if $CONFIG{help};
 my $COMMAND = do {
-    my @command = grep {exists $CONFIG{$_}} qw/repair delete rename/;
+    my @command = grep {exists $CONFIG{$_}} @COMMANDS;
     usage(1) if $#command>0;
     $command[0]
 };
@@ -200,7 +202,8 @@ $DBH->do('PRAGMA foreign_keys = ON');
 sub msg($@) {
     my $name = shift;
     return unless @_;
-    logger($name, @_) if defined $LOGGER_FD and $LOGGER_FD->fileno != fileno STDERR;
+    logger($name, @_) if defined $LOGGER_FD and defined $LOGGER_FD->fileno
+        and $LOGGER_FD->fileno != fileno STDERR;
     my $prefix = defined $name ? "$name: " : '';
     print STDERR $prefix, @_, "\n";
 }
@@ -208,7 +211,8 @@ sub logger($@) {
     my $name = shift;
     return unless @_ and defined $LOGGER_FD;
     my $prefix = '';
-    if ($LOGGER_FD->fileno != fileno STDERR) {
+    if (defined $LOGGER_FD and defined $LOGGER_FD->fileno
+            and $LOGGER_FD->fileno != fileno STDERR) {
         my ($s, $us) = Time::HiRes::gettimeofday();
         $prefix = POSIX::strftime("%b %e %H:%M:%S", localtime($s)).".$us ";
     }
index 26cfbbdad4a0539a8a6fc9c38fee3ce54cdc1737..35d207578a5ba75aca3903e9481d5d9b1fa219ce 100644 (file)
@@ -24,6 +24,7 @@ use Config::Tiny ();
 use IO::Select ();
 use List::Util 'first';
 use Socket 'SO_KEEPALIVE';
+use POSIX ':signal_h';
 
 use Exporter 'import';
 BEGIN {
@@ -225,10 +226,33 @@ sub new($%) {
     $self->{_STATE} = '';
 
     if ($self->{type} eq 'tunnel') {
-        require 'IPC/Open2.pm';
         my $command = $self->{command} // $self->fail("Missing tunnel command");
-        my $pid = IPC::Open2::open2(@$self{qw/STDOUT STDIN/}, $command)
-            or $self->panic("Can't fork: $!");
+
+        pipe $self->{STDOUT}, my $wd or $self->panic("Can't pipe: $!");
+        pipe my $rd, $self->{STDIN}  or $self->panic("Can't pipe: $!");
+
+        my $pid = fork // $self->panic("Can't fork: $!");
+
+        unless ($pid) {
+            # children
+            foreach (\*STDIN, \*STDOUT, $self->{STDIN}, $self->{STDOUT}) {
+                close $_ or $self->panic("Can't close: $!");
+            }
+            open STDIN,  '<&', $rd or $self->panic("Can't dup: $!");
+            open STDOUT, '>&', $wd or $self->panic("Can't dup: $!");
+
+            my $sigset = POSIX::SigSet::->new(SIGINT);
+            my $oldsigset = POSIX::SigSet::->new();
+
+            sigprocmask(SIG_BLOCK, $sigset, $oldsigset) // $self->panic("Can't block SIGINT: $!");
+
+            exec $command or $self->panic("Can't exec: $!");
+        }
+
+        # parent
+        foreach ($rd, $wd) {
+            close $_ or $self->panic("Can't close: $!");
+        }
     }
     else {
         my %args = (Proto => 'tcp', Blocking => 1);
@@ -287,8 +311,8 @@ sub new($%) {
     # are considered.
     $self->{_MODIFIED} = {};
 
-    if (defined $self->{'logger-fd'} and $self->{'logger-fd'}->fileno != fileno STDERR) {
-        require 'POSIX.pm';
+    if (defined $self->{'logger-fd'} and defined $self->{'logger-fd'}->fileno
+            and $self->{'logger-fd'}->fileno != fileno STDERR) {
         require 'Time/HiRes.pm';
     }
 
@@ -400,7 +424,8 @@ sub DESTROY($) {
 sub log($@) {
     my $self = shift;
     return unless @_;
-    $self->logger(@_) if defined $self->{'logger-fd'} and $self->{'logger-fd'}->fileno != fileno STDERR;
+    $self->logger(@_) if defined $self->{'logger-fd'} and defined $self->{'logger-fd'}->fileno
+        and $self->{'logger-fd'}->fileno != fileno STDERR;
     my $prefix = defined $self->{name} ? $self->{name} : '';
     $prefix .= "($self->{_SELECTED})" if $self->{_STATE} eq 'SELECTED';
     print STDERR $prefix, ': ', @_, "\n";
@@ -409,7 +434,8 @@ sub logger($@) {
     my $self = shift;
     return unless @_ and defined $self->{'logger-fd'};
     my $prefix = '';
-    if ($self->{'logger-fd'}->fileno != fileno STDERR) {
+    if (defined $self->{'logger-fd'}->fileno and defined $self->{'logger-fd'}->fileno
+            and $self->{'logger-fd'}->fileno != fileno STDERR) {
         my ($s, $us) = Time::HiRes::gettimeofday();
         $prefix = POSIX::strftime("%b %e %H:%M:%S", localtime($s)).".$us ";
     }