aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilhem Moulin <guilhem@fripost.org>2015-09-08 00:17:24 +0200
committerGuilhem Moulin <guilhem@fripost.org>2015-09-08 00:19:47 +0200
commit6a40ecf6aec13bf650645d65713c0327c6d8c5e6 (patch)
tree5ec8f1b59a6b525f5afd98cfce9796b35638ca53
parentac3e4cf6300448e9c83b45db1b769d79c6df2e38 (diff)
Block SIGINT signals to the children for type=tunnel.
So we can clean after us (and for instance remove the lockfile).
-rw-r--r--INSTALL3
-rwxr-xr-xinterimap12
-rw-r--r--lib/Net/IMAP/InterIMAP.pm40
3 files changed, 42 insertions, 13 deletions
diff --git a/INSTALL b/INSTALL
index e11e08a..7bc3eef 100644
--- 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
diff --git a/interimap b/interimap
index 6442054..a94110b 100755
--- 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 ";
}
diff --git a/lib/Net/IMAP/InterIMAP.pm b/lib/Net/IMAP/InterIMAP.pm
index 26cfbbd..35d2075 100644
--- a/lib/Net/IMAP/InterIMAP.pm
+++ b/lib/Net/IMAP/InterIMAP.pm
@@ -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 ";
}