Server IP : 85.214.239.14 / Your IP : 18.191.116.61 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/self/root/usr/share/perl5/Net/IMAP/Simple/ |
Upload File : |
package Net::IMAP::Simple::PipeSocket; use strict; use warnings; use Carp; use IPC::Open3; use IO::Select; use Symbol 'gensym'; use base 'Tie::Handle'; sub new { my $class = shift; my %args = @_; croak "command (e.g. 'ssh hostname dovecot') argument required" unless $args{cmd}; open my $fake, "+>", undef or die "initernal error dealing with blarg: $!"; ## no critic my($wtr, $rdr, $err); $err = gensym; my $pid = eval { open3($wtr, $rdr, $err, $args{cmd}) } or croak $@; my $sel = IO::Select->new($err); # my $orig = select $wtr; $|=1; # select $rdr; $|=1; # select $orig; my $this = tie *{$fake}, $class, (%args, pid=>$pid, wtr=>$wtr, rdr=>$rdr, err=>$err, sel=>$sel, ) or croak $!; return $fake; } sub UNTIE { return $_[0]->_waitpid } sub DESTROY { return $_[0]->_waitpid } sub FILENO { my $this = shift; my $rdr = $this->{rdr}; # do we mean rdr or wtr? meh? return fileno($rdr); # probably need this for select() on the read handle } sub TIEHANDLE { my $class = shift; my $this = bless {@_}, $class; return $this; } sub _chkerr { my $this = shift; my $sel = $this->{sel}; while( my @rdy = $sel->can_read(0) ) { for my $fh (@rdy) { if( eof($fh) ) { $sel->remove($fh); next; } my $line = <$fh>; warn "PIPE ERR: $line"; } } return } sub PRINT { my $this = shift; my $wtr = $this->{wtr}; $this->_chkerr; return print $wtr @_; } sub READLINE { my $this = shift; my $rdr = $this->{rdr}; $this->_chkerr; my $line = <$rdr>; return $line; } sub _waitpid { my $this = shift; if( my $pid = delete $this->{pid} ) { for my $key (qw(wtr rdr err)) { close delete $this->{$key} if exists $this->{$key}; } kill 1, $pid; # doesn't really matter if this works... we hung up all the # filehandles, so ... it's probably dead anyway. waitpid( $pid, 0 ); my $child_exit_status = $? >> 8; return $child_exit_status; } return; } sub CLOSE { my $this = shift; my $rdr = $this->{rdr}; my $wtr = $this->{wtr}; close $rdr or warn "PIPE ERR (close-r): $!"; close $wtr or warn "PIPE ERR (close-w): $!"; return; } 1; __END__ =head1 NAME Net::IMAP::Simple::PipeSocket - a little wrapper around IPC-Open3 that feels like a socket =head1 SYNOPSIS This module is really just a wrapper around IPC-Open3 that can be dropped in place of a socket handle. The L<Net::IMAP::Simple> code assumes the socket is always a socket and is never a pipe and re-writing it all would be horrible. This abstraction is used only for that purpose.