Work around race condition (not fixed, but mostly fixed)
git-svn-id: https://svn.perl.org/qpsmtpd/branches/0.31@495 958fd67b-6ff1-0310-b445-bb7760255be9
This commit is contained in:
parent
8c018d75ac
commit
11da7e2778
@ -39,12 +39,12 @@ sub hook_queue {
|
|||||||
my ($self, $transaction) = @_;
|
my ($self, $transaction) = @_;
|
||||||
|
|
||||||
# these bits inspired by Peter Samuels "qmail-queue wrapper"
|
# these bits inspired by Peter Samuels "qmail-queue wrapper"
|
||||||
pipe(MESSAGE_READER, MESSAGE_WRITER) or fault("Could not create message pipe"), exit;
|
pipe(MESSAGE_READER, MESSAGE_WRITER) or die("Could not create message pipe");
|
||||||
pipe(ENVELOPE_READER, ENVELOPE_WRITER) or fault("Could not create envelope pipe"), exit;
|
pipe(ENVELOPE_READER, ENVELOPE_WRITER) or die("Could not create envelope pipe");
|
||||||
|
|
||||||
my $child = fork();
|
my $child = fork();
|
||||||
|
|
||||||
not defined $child and fault(451, "Could not fork"), exit;
|
not defined $child and die("Could not fork");
|
||||||
|
|
||||||
if ($child) {
|
if ($child) {
|
||||||
# Parent
|
# Parent
|
||||||
@ -52,9 +52,13 @@ sub hook_queue {
|
|||||||
select(ENVELOPE_WRITER); $| = 1;
|
select(ENVELOPE_WRITER); $| = 1;
|
||||||
select($oldfh);
|
select($oldfh);
|
||||||
|
|
||||||
close MESSAGE_READER or fault("close msg reader fault"),exit;
|
close MESSAGE_READER or die("close msg reader fault");
|
||||||
close ENVELOPE_READER or fault("close envelope reader fault"), exit;
|
close ENVELOPE_READER or die("close envelope reader fault");
|
||||||
|
|
||||||
|
# Note - technically there's a race here because if the exec() below
|
||||||
|
# fails and the writes to MESSAGE_WRITER block we get a deadlocked process.
|
||||||
|
# This check to see if(eof(PIPE)) will catch "most" of these problems.
|
||||||
|
die "Message pipe has been closed" if eof(MESSAGE_WRITER);
|
||||||
$transaction->header->print(\*MESSAGE_WRITER);
|
$transaction->header->print(\*MESSAGE_WRITER);
|
||||||
$transaction->body_resetpos;
|
$transaction->body_resetpos;
|
||||||
while (my $line = $transaction->body_getline) {
|
while (my $line = $transaction->body_getline) {
|
||||||
@ -64,6 +68,7 @@ sub hook_queue {
|
|||||||
|
|
||||||
my @rcpt = map { "T" . $_->address } $transaction->recipients;
|
my @rcpt = map { "T" . $_->address } $transaction->recipients;
|
||||||
my $from = "F".($transaction->sender->address|| "" );
|
my $from = "F".($transaction->sender->address|| "" );
|
||||||
|
die "Envelope pipe has been closed" if eof(ENVELOPE_WRITER);
|
||||||
print ENVELOPE_WRITER "$from\0", join("\0",@rcpt), "\0\0"
|
print ENVELOPE_WRITER "$from\0", join("\0",@rcpt), "\0\0"
|
||||||
or return(DECLINED,"Could not print addresses to queue");
|
or return(DECLINED,"Could not print addresses to queue");
|
||||||
|
|
||||||
@ -104,6 +109,10 @@ sub hook_queue {
|
|||||||
|
|
||||||
my $rc = exec $queue_exec;
|
my $rc = exec $queue_exec;
|
||||||
|
|
||||||
|
# close the pipe
|
||||||
|
close(MESSAGE_READER);
|
||||||
|
close(MESSAGE_WRITER);
|
||||||
|
|
||||||
exit 6; # we'll only get here if the exec fails
|
exit 6; # we'll only get here if the exec fails
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user