File Coverage

blib/lib/Term/CallEditor.pm
Criterion Covered Total %
statement 24 71 33.8
branch 0 38 0.0
condition 0 16 0.0
subroutine 8 10 80.0
pod 0 1 0.0
total 32 136 23.5


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # Solicits data from an external editor as determined by the EDITOR
4             # environment variable. Run perldoc(1) on this module for additional
5             # documentation.
6             #
7             # Copyright 2004-2005,2009-2010,2012 Jeremy Mates
8             #
9             # This module is free software; you can redistribute it and/or modify it
10             # under the Artistic license.
11              
12             package Term::CallEditor;
13              
14 2     2   28514 use strict;
  2         3  
  2         64  
15 2     2   8 use warnings;
  2         3  
  2         154  
16              
17             require 5.006;
18              
19 2     2   7 use vars qw(@EXPORT @ISA $VERSION $errstr);
  2         12  
  2         130  
20             @EXPORT = qw(solicit);
21             @ISA = qw(Exporter);
22 2     2   6 use Exporter;
  2         2  
  2         66  
23              
24 2     2   6 use Fcntl qw(:DEFAULT :flock);
  2         2  
  2         619  
25 2     2   1154 use File::Temp qw(tempfile);
  2         31013  
  2         102  
26 2     2   12 use IO::Handle;
  2         2  
  2         57  
27              
28 2     2   737 use POSIX qw(getpgrp tcgetpgrp);
  2         10904  
  2         18  
29              
30             $VERSION = '0.66';
31              
32             sub solicit {
33 0     0 0   my $message = shift;
34 0   0       my $params = shift || {};
35              
36 0 0 0       unless ( exists $params->{skip_interative} and $params->{skip_interative} ) {
37 0 0         return unless _is_interactive();
38             }
39              
40 0 0         File::Temp->safe_level( $params->{safe_level} ) if exists $params->{safe_level};
41 0           my ( $tfh, $filename ) = tempfile( UNLINK => 1 );
42              
43 0 0 0       unless ( $tfh and $filename ) {
44 0           $errstr = 'no temporary file';
45 0           return;
46             }
47              
48 0 0 0       if ( exists $params->{binmode_layer}
    0 0        
49             and defined $params->{binmode_layer} ) {
50 0           binmode( $tfh, $params->{binmode_layer} );
51             } elsif ( exists $params->{BINMODE} and $params->{BINMODE} ) {
52 0           binmode($tfh);
53             }
54              
55 0           select( ( select($tfh), $|++ )[0] );
56              
57 0 0         if ( defined $message ) {
58 0           my $ref = ref $message;
59 0 0         if ( not $ref ) {
    0          
    0          
    0          
    0          
60 0           print $tfh $message;
61             } elsif ( $ref eq 'SCALAR' ) {
62 0           print $tfh $$message;
63             } elsif ( $ref eq 'ARRAY' ) {
64 0           print $tfh "@$message";
65             } elsif ( $ref eq 'GLOB' ) {
66 0           while ( my $line = <$message> ) {
67 0           print $tfh $line;
68             }
69             } elsif ( UNIVERSAL::can( $message, 'getlines' ) ) {
70 0           print $tfh $message->getlines;
71             }
72             # Help the bits reach the disk
73 0           $tfh->flush();
74             # TODO may need eval or exclude on other platforms
75 0 0         if ( $^O !~ m/Win32/ ) {
76 0           $tfh->sync();
77             }
78             }
79              
80 0   0       my $editor = $ENV{EDITOR} || 'vi';
81              
82             # need to unlock for external editor
83 0           flock $tfh, LOCK_UN;
84              
85 0           my $status = system $editor, $filename;
86 0 0         if ( $status != 0 ) {
87 0 0         $errstr =
88             ( $status != -1 )
89             ? "external editor failed: editor=$editor, errstr=$?"
90             : "could not launch program: editor=$editor, errstr=$!";
91 0           return;
92             }
93              
94             # Must reopen filename, as editor could have done a rename() on us, in
95             # which case the $tfh is then invalid.
96 0           my $outfh;
97 0 0         unless ( open( $outfh, '<', $filename ) ) {
98 0           $errstr = "could not reopen tmp file: errstr=$!";
99 0           return;
100             }
101              
102 0 0         return wantarray ? ( $outfh, $filename ) : $outfh;
103             }
104              
105             # Perl CookBook code to check whether terminal is interactive
106             sub _is_interactive {
107 0     0     my $tty;
108 0 0         unless ( open $tty, '<', '/dev/tty' ) {
109 0           $errstr = "cannot open /dev/tty: errno=$!";
110 0           return;
111             }
112 0           my $tpgrp = tcgetpgrp fileno $tty;
113 0           my $pgrp = getpgrp();
114 0           close $tty;
115 0 0         unless ( $tpgrp == $pgrp ) {
116 0           $errstr = "no exclusive control of tty: pgrp=$pgrp, tpgrp=$tpgrp";
117 0           return;
118             }
119 0           return 1;
120             }
121              
122             1;
123              
124             __END__