File Coverage

blib/lib/Protocol/DBus/WriteMsg.pm
Criterion Covered Total %
statement 29 36 80.5
branch 4 12 33.3
condition 2 3 66.6
subroutine 9 9 100.0
pod 0 1 0.0
total 44 61 72.1


line stmt bran cond sub pod time code
1             package Protocol::DBus::WriteMsg;
2              
3 6     6   31 use strict;
  6         12  
  6         151  
4 6     6   25 use warnings;
  6         7  
  6         119  
5              
6 6     6   24 use Socket ();
  6         12  
  6         62  
7              
8 6     6   1628 use Protocol::DBus::Socket ();
  6         12  
  6         123  
9              
10 6     6   30 use parent qw( IO::Framed::Write );
  6         12  
  6         69  
11              
12             my %fh_fds;
13              
14             sub DESTROY {
15 5     5   12637 my ($self) = @_;
16              
17 5         38 my $fh = delete $fh_fds{ $self->get_write_fh() };
18              
19 5 50       83 $self->SUPER::DESTROY() if IO::Framed::Write->can('DESTROY');
20              
21 5         116 return;
22             }
23              
24             sub enqueue_message {
25 6     6 0 28 my ($self, $buf_sr, $fds_ar, $on_send) = @_;
26              
27 6 50 66     12 push @{ $fh_fds{$self->get_write_fh()} }, ($fds_ar && @$fds_ar) ? $fds_ar : undef;
  6         78  
28              
29             $self->write(
30             $$buf_sr,
31             sub {
32              
33             # We’re done with the message, so we remove the FDs entry,
34             # which by here should be undef.
35 6     6   280 shift @{ $fh_fds{$self->get_write_fh()} };
  6         18  
36              
37 6 50       35 $on_send->() if $on_send;
38             },
39 6         176 );
40              
41 6         92 return $self;
42             }
43              
44             # Receives ($fh, $buf)
45             sub WRITE {
46              
47             # Only use sendmsg if we actually need to.
48 6 50   6   130 if (my $fds_ar = $fh_fds{ $_[0] }[0]) {
49 0 0       0 die 'Socket::MsgHdr is not loaded!' if !Socket::MsgHdr->can('new');
50              
51 0         0 my $msg = Socket::MsgHdr->new( buf => $_[1] );
52              
53 0         0 $msg->cmsghdr(
54             Socket::SOL_SOCKET(), Socket::SCM_RIGHTS(),
55             pack( 'I!*', @$fds_ar ),
56             );
57              
58 0         0 my $bytes = Protocol::DBus::Socket::sendmsg_nosignal( $_[0], $msg, 0 );
59              
60             # NOTE: This assumes that, on an incomplete write, the ancillary
61             # data (i.e., the FDs) will have been sent, and there is no need
62             # to resend. That appears to be the case on Linux and MacOS, but
63             # I can’t find any actual documentation to that effect.
64 0 0       0 if ($bytes) {
65 0         0 undef $fh_fds{ $_[0] }[0];
66             }
67              
68 0         0 return $bytes;
69             }
70              
71 6         43 return Protocol::DBus::Socket::send_nosignal( $_[0], $_[1], 0 );
72             }
73              
74             1;