croak "@exc" if @exc;
}
+sub sendmsg_eor ($$$;$) {
+ my $n = $send_cmd->($_[0], $_[1], $_[2], MSG_EOR, $_[3] // 50) //
+ return;
+ $n == length($_[2]) ? $n : croak('sendmsg('.length($_[2])." > $n)");
+}
+
sub stream_in_full ($$$) {
my ($s1, $io, $buf) = @_;
socketpair(my $r, my $w, AF_UNIX, SOCK_STREAM, 0);
- my $n = $send_cmd->($s1, [ $r ],
- ipc_freeze(['do_sock_stream', length($buf)]),
- MSG_EOR) // croak "sendmsg: $!";
+ my $n = sendmsg_eor($s1, [ $r ],
+ ipc_freeze(['do_sock_stream', length($buf)]))
+ // croak "sendmsg: $!";
undef $r;
$n = $send_cmd->($w, $io, $buf, 0) // croak "sendmsg: $!";
print $w substr($buf, $n) if $n < length($buf); # need > 2G on Linux
- close $w; # autodies
+ close $w; # autodies if print failed
}
sub wq_io_do { # always async
my $buf = ipc_freeze([$sub, @args]);
if (length($buf) > $MY_MAX_ARG_LEN) {
stream_in_full($s1, $io, $buf);
+ } elsif (defined sendmsg_eor($s1, $io, $buf)) {
+ # success
} else {
- my $n = $send_cmd->($s1, $io, $buf, MSG_EOR);
- return if defined($n); # likely
$!{ETOOMANYREFS} and croak "sendmsg: $! (check RLIMIT_NOFILE)";
$!{EMSGSIZE} ? stream_in_full($s1, $io, $buf) :
croak("sendmsg: $!");
my $buf = ipc_freeze([$sub, @args]);
if ($self->{wqb}) { # saturated once, assume saturated forever
$self->{wqb}->flush_send($buf);
- } elsif (!defined $send_cmd->($self->{-wq_s1}, [], $buf, MSG_EOR)) {
- if ($!{EAGAIN} || $!{ENOBUFS} || $!{ENOMEM}) {
- PublicInbox::WQBlocked->new($self, $buf);
- } else {
- croak "sendmsg: $!";
- }
- } # else success
+ } elsif (defined sendmsg_eor($self->{-wq_s1}, [], $buf)) {
+ # success!
+ } elsif ($!{EAGAIN} || $!{ENOBUFS} || $!{ENOMEM}) {
+ PublicInbox::WQBlocked->new($self, $buf);
+ } else {
+ croak "sendmsg: $!";
+ }
}
sub _wq_worker_start {
PublicInbox::LeiQuery);
use autodie qw(bind chdir listen open pipe socket socketpair syswrite unlink);
use Getopt::Long ();
-use Socket qw(AF_UNIX SOCK_SEQPACKET pack_sockaddr_un MSG_EOR);
+use Socket qw(AF_UNIX SOCK_SEQPACKET pack_sockaddr_un);
use Errno qw(EPIPE EAGAIN ECONNREFUSED ENOENT ECONNRESET EINTR);
use Cwd qw(getcwd);
use POSIX qw(strftime);
sub send_exec_cmd { # tell script/lei to execute a command
my ($self, $io, $cmd, $env) = @_;
- $PublicInbox::IPC::send_cmd->(
+ PublicInbox::IPC::sendmsg_eor(
$self->{sock} // die('lei client gone'),
- $io, exec_buf($cmd, $env), MSG_EOR) //
+ $io, exec_buf($cmd, $env)) //
Carp::croak("sendmsg: $!");
}
use v5.12;
use parent qw(PublicInbox::DS);
use PublicInbox::Syscall qw(EPOLLOUT EPOLLONESHOT);
-use Socket qw(MSG_EOR);
use PublicInbox::IPC;
use Carp ();
while (defined(my $buf = shift @{$self->{msgq}})) {
if (ref($buf) eq 'CODE') {
$buf->($self); # could be \&PublicInbox::DS::close
+ } elsif (defined(PublicInbox::IPC::sendmsg_eor(
+ $self->{sock}, [], $buf))) {
+ # success
} else {
- my $wq_s1 = $self->{sock};
- my $n = $PublicInbox::IPC::send_cmd->($wq_s1, [], $buf,
- MSG_EOR);
- next if defined($n);
if ($!{EAGAIN}) {
- PublicInbox::DS::epwait($wq_s1,
+ PublicInbox::DS::epwait($self->{sock},
EPOLLOUT|EPOLLONESHOT);
} elsif ($!{ENOBUFS} || $!{ENOMEM}) {
PublicInbox::DS::add_uniq_timer($self + 0,
package PublicInbox::XapClient;
use v5.12;
use PublicInbox::Spawn qw(spawn);
-use Socket qw(AF_UNIX SOCK_SEQPACKET MSG_EOR);
+use Carp qw(croak);
+use Socket qw(AF_UNIX SOCK_SEQPACKET);
use PublicInbox::IPC;
use autodie qw(pipe socketpair);
our $tries = -1; # set to zero by read-only daemon
sub mkreq {
my ($self, $io, @arg) = @_;
my $buf = join("\0", @arg, '');
- my $n = $PublicInbox::IPC::send_cmd->($self->{io},
- $io, $buf, MSG_EOR, $tries)
- // die "send_cmd: $!";
- $n == length($buf) or die "send_cmd: $n != ".length($buf);
+ PublicInbox::IPC::sendmsg_eor($self->{io}, $io, $buf, $tries) //
+ croak "sendmsg_eor: $!";
}
sub start_helper (@) {
# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
use strict; use v5.10.1; use PublicInbox::TestCommon;
-use Socket qw(AF_UNIX SOCK_SEQPACKET pack_sockaddr_un MSG_EOR);
+use Socket qw(AF_UNIX SOCK_SEQPACKET pack_sockaddr_un);
+require PublicInbox::IPC;
test_lei({ daemon_only => 1 }, sub {
- my $send_cmd = PublicInbox::Spawn->can('send_cmd4') // do {
- require PublicInbox::Syscall;
- PublicInbox::Syscall->can('send_cmd4');
- };
- $send_cmd or BAIL_OUT 'started testing lei-daemon w/o send_cmd4!';
-
my $sock = "$ENV{XDG_RUNTIME_DIR}/lei/5.seq.sock";
my $err_log = "$ENV{XDG_RUNTIME_DIR}/lei/errors.log";
lei_ok('daemon-pid');
socket(my $c, AF_UNIX, SOCK_SEQPACKET, 0) or
BAIL_OUT "socket: $!";
connect($c, $addr) or BAIL_OUT "connect: $!";
- $send_cmd->($c, [ $null, $null, $null ], 'hi', MSG_EOR);
+ PublicInbox::IPC::sendmsg_eor($c,
+ [ $null, $null, $null ], 'hi');
}
lei_ok('daemon-pid');
chomp($pid = $lei_out);
use PublicInbox::TestCommon;
require_mods(qw(DBD::SQLite Xapian +SCM_RIGHTS)); # TODO: FIFO support?
use PublicInbox::Spawn qw(spawn);
-use Socket qw(AF_UNIX SOCK_SEQPACKET SOCK_STREAM MSG_EOR);
+use Socket qw(AF_UNIX SOCK_SEQPACKET SOCK_STREAM);
require PublicInbox::AutoReap;
use PublicInbox::IPC;
require PublicInbox::XapClient;
pipe(my $x, my $y);
my $buf = join("\0", @arg, '');
my @io = ($y, $err);
- my $n = $PublicInbox::IPC::send_cmd->($s, \@io, $buf, MSG_EOR) //
- xbail "send: $!";
+ my $n = PublicInbox::IPC::sendmsg_eor($s, \@io, $buf) //
+ xbail "sendmsg: $!";
my $exp = length($buf);
$exp == $n or xbail "req @arg sent short ($n != $exp)";
$x;