#!perl -w # Copyright (C) all contributors # License: AGPL-3.0+ # This talks to (XapHelperCxx.pm + xap_helper.h) or XapHelper.pm # and will eventually allow users with neither XS nor SWIG Perl # bindings to use Xapian as long as they have Xapian development # headers/libs and a C++ compiler package PublicInbox::XapClient; use v5.12; use PublicInbox::Spawn qw(spawn); use Socket qw(AF_UNIX SOCK_SEQPACKET); use PublicInbox::IPC; use autodie qw(pipe socketpair); our $tries = 50; sub mkreq { my ($self, $ios, @arg) = @_; my ($r, $n); pipe($r, $ios->[0]) if !defined($ios->[0]); my @fds = map fileno($_), @$ios; my $buf = join("\0", @arg, ''); $n = $PublicInbox::IPC::send_cmd->($self->{io}, \@fds, $buf, 0, $tries) // die "send_cmd: $!"; $n == length($buf) or die "send_cmd: $n != ".length($buf); $r; } sub start_helper (@) { $PublicInbox::IPC::send_cmd or return; # can't work w/o SCM_RIGHTS my @argv = @_; socketpair(my $sock, my $in, AF_UNIX, SOCK_SEQPACKET, 0); my $cls = 'PublicInbox::XapHelperCxx'; my $env; my $cmd = eval "require $cls; ${cls}::cmd()"; if ($@) { # fall back to Perl + XS|SWIG $cls = 'PublicInbox::XapHelper'; # ensure the child process has the same @INC we do: $env = { PERL5LIB => join(':', @INC) }; $cmd = [$^X, ($^W ? ('-w') : ()), "-M$cls", '-e', $cls.'::start(@ARGV)', '--' ]; } push @$cmd, @argv; my $pid = spawn($cmd, $env, { 0 => $in }); my $self = bless { io => $sock, impl => $cls }, __PACKAGE__; PublicInbox::IO::attach_pid($sock, $pid); $self; } 1;