r57726 - in /trunk/libparanoid-perl: CHANGELOG META.yml debian/changelog lib/Paranoid.pm lib/Paranoid/Input.pm lib/Paranoid/Process.pm t/02_input.t

jawnsy-guest at users.alioth.debian.org jawnsy-guest at users.alioth.debian.org
Sun May 9 05:06:20 UTC 2010


Author: jawnsy-guest
Date: Sun May  9 05:04:47 2010
New Revision: 57726

URL: http://svn.debian.org/wsvn/pkg-perl/?sc=1&rev=57726
Log:
integrate new upstream release

Modified:
    trunk/libparanoid-perl/CHANGELOG
    trunk/libparanoid-perl/META.yml
    trunk/libparanoid-perl/debian/changelog
    trunk/libparanoid-perl/lib/Paranoid.pm
    trunk/libparanoid-perl/lib/Paranoid/Input.pm
    trunk/libparanoid-perl/lib/Paranoid/Process.pm
    trunk/libparanoid-perl/t/02_input.t

Modified: trunk/libparanoid-perl/CHANGELOG
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libparanoid-perl/CHANGELOG?rev=57726&op=diff
==============================================================================
--- trunk/libparanoid-perl/CHANGELOG (original)
+++ trunk/libparanoid-perl/CHANGELOG Sun May  9 05:04:47 2010
@@ -1,4 +1,14 @@
 CHANGELOG
+
+v0.25 (2010/05/05)
+==================
+--Fixed tail's behavior to be consistent with documentation
+--Fixed tail/sip to preserve file position and buffers when 
+  reopening the file in children
+--Fixed tail functionality to handle deleted, truncated, moved, or replaced
+  files
+--Expanded tail/sip documentation
+--Added daemonize function to Paranoid::Process
 
 v0.24 (2010/04/15)
 ==================

Modified: trunk/libparanoid-perl/META.yml
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libparanoid-perl/META.yml?rev=57726&op=diff
==============================================================================
--- trunk/libparanoid-perl/META.yml (original)
+++ trunk/libparanoid-perl/META.yml Sun May  9 05:04:47 2010
@@ -1,6 +1,6 @@
 --- #YAML:1.0
 name:               Paranoid
-version:            0.24
+version:            0.25
 abstract:           General function library for safer, more secure programming
 author:
     - Arthur Corliss <corliss at digitalmages.com>

Modified: trunk/libparanoid-perl/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libparanoid-perl/debian/changelog?rev=57726&op=diff
==============================================================================
--- trunk/libparanoid-perl/debian/changelog (original)
+++ trunk/libparanoid-perl/debian/changelog Sun May  9 05:04:47 2010
@@ -1,4 +1,4 @@
-libparanoid-perl (0.24-1) UNRELEASED; urgency=low
+libparanoid-perl (0.25-1) UNRELEASED; urgency=low
 
   NOTEs from jawnsy:
   - builds fine on amd64 and i386 sbuild chroots
@@ -48,7 +48,7 @@
   * debian/control: add libberkeleydb-perl, libunix-syslog-perl to
     Build-Depends-Indep (additional tests).
 
- -- Jonathan Yu <jawnsy at cpan.org>  Mon, 03 May 2010 10:54:01 -0400
+ -- Jonathan Yu <jawnsy at cpan.org>  Sun, 09 May 2010 01:39:56 -0400
 
 libparanoid-perl (0.23-1) unstable; urgency=low
 

Modified: trunk/libparanoid-perl/lib/Paranoid.pm
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libparanoid-perl/lib/Paranoid.pm?rev=57726&op=diff
==============================================================================
--- trunk/libparanoid-perl/lib/Paranoid.pm (original)
+++ trunk/libparanoid-perl/lib/Paranoid.pm Sun May  9 05:04:47 2010
@@ -2,7 +2,7 @@
 #
 # (c) 2005, Arthur Corliss <corliss at digitalmages.com>
 #
-# $Id: Paranoid.pm,v 0.24 2010/04/15 23:20:43 acorliss Exp $
+# $Id: Paranoid.pm,v 0.25 2010/05/05 00:20:17 acorliss Exp $
 #
 #    This software is licensed under the same terms as Perl, itself.
 #    Please see http://dev.perl.org/licenses/ for more information.
@@ -24,7 +24,7 @@
 use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS);
 use base qw(Exporter);
 
-($VERSION) = ( q$Revision: 0.24 $ =~ /(\d+(?:\.(\d+))+)/sm );
+($VERSION) = ( q$Revision: 0.25 $ =~ /(\d+(?:\.(\d+))+)/sm );
 
 @EXPORT      = qw(psecureEnv);
 @EXPORT_OK   = qw(psecureEnv);
@@ -98,7 +98,7 @@
 
 =head1 VERSION
 
-$Id: Paranoid.pm,v 0.24 2010/04/15 23:20:43 acorliss Exp $
+$Id: Paranoid.pm,v 0.25 2010/05/05 00:20:17 acorliss Exp $
 
 =head1 SYNOPSIS
 

Modified: trunk/libparanoid-perl/lib/Paranoid/Input.pm
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libparanoid-perl/lib/Paranoid/Input.pm?rev=57726&op=diff
==============================================================================
--- trunk/libparanoid-perl/lib/Paranoid/Input.pm (original)
+++ trunk/libparanoid-perl/lib/Paranoid/Input.pm Sun May  9 05:04:47 2010
@@ -2,7 +2,7 @@
 #
 # (c) 2005, Arthur Corliss <corliss at digitalmages.com>
 #
-# $Id: Input.pm,v 0.16 2010/04/15 23:23:28 acorliss Exp $
+# $Id: Input.pm,v 0.19 2010/05/05 23:30:33 acorliss Exp $
 #
 #    This software is licensed under the same terms as Perl, itself.
 #    Please see http://dev.perl.org/licenses/ for more information.
@@ -28,7 +28,7 @@
 use Paranoid::Debug qw(:all);
 use Carp;
 
-($VERSION) = ( q$Revision: 0.16 $ =~ /(\d+(?:\.(\d+))+)/sm );
+($VERSION) = ( q$Revision: 0.19 $ =~ /(\d+(?:\.(\d+))+)/sm );
 
 @EXPORT = qw(FSZLIMIT LNSZLIMIT slurp sip tail closeFile
     detaint stringMatch);
@@ -41,6 +41,12 @@
         ],
         );
 
+use constant STAT_INO  => 1;
+use constant STAT_SIZE => 7;
+use constant DEF_FSIZE => 16 * 1024;
+use constant DEF_LSIZE => 2 * 1024;
+use constant RV_LSZERR => -1;
+
 #####################################################################
 #
 # Module code follows
@@ -48,7 +54,7 @@
 #####################################################################
 
 {
-    my $fszlimit = 16 * 1024;
+    my $fszlimit = DEF_FSIZE;
 
     sub FSZLIMIT : lvalue {
 
@@ -60,7 +66,7 @@
         $fszlimit;
     }
 
-    my $lnszlimit = 2 * 1024;
+    my $lnszlimit = DEF_LSIZE;
 
     sub LNSZLIMIT : lvalue {
 
@@ -175,6 +181,7 @@
 {
     my %fhandles;    # Hash of filenames => filedescriptors
     my %fpids;       # Hash of filenames => opening PIDs
+    my %fstat;       # Hash of filenames => [ stat info ]
     my %buffers;     # Hash of strings, keyed by filename
 
     sub closeFile {
@@ -193,10 +200,11 @@
         pdebug( "entering w/($filename)", PDLEVEL1 );
         pIn();
 
-        if ( exists $fhandles{$filename} && $fpids{$filename} == $$ ) {
+        if ( exists $fhandles{$filename} ) {
             $rv = close $fhandles{$filename};
             delete $fhandles{$filename};
             delete $fpids{$filename};
+            delete $fstat{$filename};
             delete $buffers{$filename};
         }
 
@@ -208,17 +216,33 @@
 
     sub _getHandle {
 
-        # Purpose:  Retrieves a filehandle to the requested file.  It also
-        #           tracks what process opened the filehandle so a new one is
-        #           opened after a fork call.  Passing the optional boolean
-        #           field as true will cause the file pointer to be sent to
-        #           the end of the file.
+        # Purpose:  This is a unified function that serves retrieval of file
+        #           handles for both sip & tail.  For both, it pays attention
+        #           to whether the file was opened before a fork, and if so,
+        #           closes the file handle in the child and reopens it, albeit
+        #           at the same position.
+        #
+        #           Invocation differs between sip & tail, however.  For sip
+        #           all it needs is the filename.  For tail it expects one or
+        #           two more arguments.  The first boolean argument tells the
+        #           function that it's being called in tail mode, and should
+        #           seek to the end of the file on file opens.  The second
+        #           argument is an optional offset to back up from the EOF on
+        #           new opens.
+        #
+        #           Finally, tail mode also keeps track of the file stat
+        #           information on each call.  It uses that to detect when
+        #           either the file is truncated or moved so that we can
+        #           reopen the filehandle and continue tailing.  This is
+        #           useful in situations such as in log rotation.
         # Returns:  Filehandle
         # Usage:    $fh = _getHandle($filename);
+        # Usage:    $fh = _getHandle($filename, 1, -25);
 
         my $filename = shift;
         my $seekEOF  = shift;
-        my ( $f, $fd, $rv );
+        my $offset   = shift || 0;
+        my ( $f, $fd, $rv, @fstat, $bpos, $buffer );
 
         # Is there a filehandle cached?
         if ( exists $fhandles{$filename} ) {
@@ -226,14 +250,73 @@
             # Yes, so was it opened by us?
             if ( $fpids{$filename} == $$ ) {
 
-                # Yup, return the filehandle
-                $rv = $fhandles{$filename};
+                if ($seekEOF) {
+
+                    # In tail mode let's stat the file handle
+                    $fstat{$filename} = [ stat $fhandles{$filename} ];
+                    $bpos = tell $fhandles{$filename};
+
+                    if ( $bpos < $fstat{$filename}[STAT_SIZE] ) {
+
+                        # shortcut:  if the file size is greater than
+                        #            current position we know we still have
+                        #            content to read, so continue as normal
+                        $rv = $fhandles{$filename};
+
+                    } else {
+
+                        # See what's currently on the filesystem answering to
+                        # this filename
+                        @fstat = stat $filename;
+
+                        if ( @fstat == 0 ) {
+
+                            # OMG -- they killed Kenny!  You bastards!
+                            Paranoid::ERROR =
+                                pdebug( "$filename has been deleted",
+                                PDLEVEL3 );
+                            $rv = undef;
+
+                        } elsif (
+                            $fstat[STAT_INO] != $fstat{$filename}[STAT_INO]
+                            or
+                            ( $fstat[STAT_INO] == $fstat{$filename}[STAT_INO]
+                                and $bpos > $fstat{$filename}[STAT_SIZE] )
+                            ) {
+
+                            # The file was truncated, moved, or replaced.
+                            # Either way, we need to reopen the file
+                            # from the beginning
+                            pdebug(
+                                "$filename has been truncated, moved, "
+                                    . 'or replaced -- reopening',
+                                PDLEVEL3
+                                );
+                            closeFile($filename);
+                            $rv = _getHandle($filename);
+
+                        } else {
+
+                            # When all else fails, give them the filehandle on
+                            # file...
+                            $rv = $fhandles{$filename};
+                        }
+                    }
+                } else {
+
+                    # Sip mode
+                    $rv = $fhandles{$filename};
+                }
 
             } else {
 
-                # Nope, let's delete it and reopen it
-                delete $fhandles{$filename};
+                pdebug( "reopening $filename", PDLEVEL3 );
+                $bpos = tell $fhandles{$filename};
+                $buffer = $buffers{$filename} if exists $buffers{$filename};
+                closeFile($filename);
                 $rv = _getHandle($filename);
+                seek $rv, $bpos, SEEK_SET;
+                $buffers{$filename} = $buffer if defined $buffer;
             }
 
         } else {
@@ -242,13 +325,22 @@
             if ( detaint( $filename, 'filename', \$f ) ) {
 
                 # Try to open the file
+                pdebug( "opening $filename", PDLEVEL3 );
                 if ( sysopen $fd, $f, O_RDONLY ) {
 
                     # Done, now cache and return the filehandle
                     $fhandles{$f} = $fd;
                     $fpids{$f}    = $$;
+                    $fstat{$f}    = [ stat $f ];
                     $buffers{$f}  = '';
                     $rv           = $fd;
+
+                    # If seekEOF is set, let's go to the end minus the offset
+                    if ($seekEOF) {
+                        pdebug( "moving to EOF offset $offset", PDLEVEL3 );
+                        seek $fd, $offset, SEEK_END;
+                        seek $fd, 0, SEEK_CUR;
+                    }
 
                 } else {
 
@@ -339,7 +431,7 @@
                             );
                         $buffers{$filename} = substr $buffers{$filename}, 0,
                             LNSZLIMIT +1;
-                        $rv = -1;
+                        $rv = RV_LSZERR;
                     }
                 } else {
 
@@ -354,7 +446,7 @@
                         pdebug( 'removing line exceeding ' . LNSZLIMIT,
                             PDLEVEL2 );
                         splice @$aref, $i, 1;
-                        $rv = -1;
+                        $rv = RV_LSZERR;
                     } else {
                         $i++;
                     }
@@ -384,7 +476,7 @@
         my $aref      = shift;
         my $offset    = shift || 0;
         my $autoChomp = shift || 0;
-        my $rv        = 0;
+        my $rv        = 1;
         my ( $fd, $bpos, $ofszlimit );
 
         croak 'Mandatory first argument must be a defined filename'
@@ -397,20 +489,11 @@
         pIn();
 
         # Get the file descriptor
-        $fd = _getHandle($filename);
+        $offset *= LNSZLIMIT +1;
+        $fd = _getHandle( $filename, 1, $offset );
         if ( defined $fd ) {
 
-            # Find out our current byte position
-            $bpos = tell $fd;
-
-            # If we're on byte 0 we will assume that this is the first time
-            # tail has been called on this file, and that this call is the one
-            # that opened the file.  In which case we'll seek to the EOF -
-            # offset before calling sip
-            unless ($bpos) {
-                $offset *= LNSZLIMIT +1;
-                pdebug( "moving to EOF $offset", PDLEVEL2 );
-                seek $fd, $offset, SEEK_END;
+            if ($offset) {
 
                 # We also need to temporarily change FSZLIMIT so we can get
                 # all of our back input in one fell swoop
@@ -419,17 +502,19 @@
             }
 
             # Now, call sip
-            $rv = sip( $filename, $aref, $autoChomp );
+            sip( $filename, $aref, $autoChomp );
 
             # Restore FSZLIMIT if this was the initial call, and prune excess
             # lines found
-            unless ($bpos) {
+            if ($offset) {
                 FSZLIMIT = $ofszlimit;
                 $offset = abs $offset / LNSZLIMIT +1;
                 if ( $offset < @$aref ) {
                     splice @$aref, 0, @$aref - $offset;
                 }
             }
+        } else {
+            $rv = 0;
         }
 
         pOut();
@@ -595,7 +680,7 @@
 
 =head1 VERSION
 
-$Id: Input.pm,v 0.16 2010/04/15 23:23:28 acorliss Exp $
+$Id: Input.pm,v 0.19 2010/05/05 23:30:33 acorliss Exp $
 
 =head1 SYNOPSIS
 
@@ -623,6 +708,19 @@
 The modules provide safer routines to use for input activities such as reading
 files and detainting user input.
 
+The B<sip> and B<tail> functions keep open file handles.  Even so, it's
+specifically built to be safe for use in B<fork> scenarios.  You can being a
+tail or sip in a parent, fork children, and all process can independently
+continue sipping with no confusion between processes.  This is possible
+because we check to see if the PID matches the PID in effect with the file was
+opened.  If not, we reopen the file and seek to the same position so we can
+pick up where we left off.
+
+The B<slurp> function isn't affected by this since it reads entire files in a
+single call, no filehandles are kept open between calls.
+
+All file-reading functions use and obey B<flock>.
+
 B<addTaintRegex> is only exported if this module is used with the B<:all> target.
 
 =head1 SUBROUTINES/METHODS
@@ -679,6 +777,8 @@
 When sip comes up to then end of the file it does not close the file, you're
 required to close it explicitly with B<closeFile>.  This is done intentionally
 to allow the process to continue to effectively B<tail> a growing file.
+Unlike the B<tail> function provided here, though, it does perform any
+additional checks to see if the file you're reading was truncated or replaced.
 
 An optional third argument tells sip whether or not to chomp all the read
 lines before returning.
@@ -698,6 +798,10 @@
 This function returns true if the file is successfully open, regardless of
 whether any new input was there to be read.  It only returns false if there 
 was a problem opening or reading the file.
+
+Tail should be called with the third argument for the first tail of a file.
+Continuing to use it for subsequent calls will cause the number of lines
+returned to be truncated to fit within that limit.
 
 Like B<sip>, one must explicitly close a file with B<closeFile>.
 

Modified: trunk/libparanoid-perl/lib/Paranoid/Process.pm
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libparanoid-perl/lib/Paranoid/Process.pm?rev=57726&op=diff
==============================================================================
--- trunk/libparanoid-perl/lib/Paranoid/Process.pm (original)
+++ trunk/libparanoid-perl/lib/Paranoid/Process.pm Sun May  9 05:04:47 2010
@@ -2,7 +2,7 @@
 #
 # (c) 2005, Arthur Corliss <corliss at digitalmages.com>
 #
-# $Id: Process.pm,v 0.95 2010/04/15 23:23:28 acorliss Exp $
+# $Id: Process.pm,v 0.99 2010/05/06 07:42:50 acorliss Exp $
 #
 #    This software is licensed under the same terms as Perl, itself.
 #    Please see http://dev.perl.org/licenses/ for more information.
@@ -25,24 +25,26 @@
 use base qw(Exporter);
 use Paranoid;
 use Paranoid::Debug qw(:all);
-use POSIX qw(getuid setuid setgid WNOHANG);
+use POSIX qw(getuid setuid setgid WNOHANG setsid);
 use Carp;
 
-($VERSION) = ( q$Revision: 0.95 $ =~ /(\d+(?:\.(\d+))+)/sm );
-
- at EXPORT    = qw(switchUser);
+($VERSION) = ( q$Revision: 0.99 $ =~ /(\d+(?:\.(\d+))+)/sm );
+
+ at EXPORT    = qw(switchUser daemonize);
 @EXPORT_OK = qw(MAXCHILDREN      childrenCount   installChldHandler
     sigchld          pfork           ptranslateUser
-    ptranslateGroup  switchUser      pcapture);
+    ptranslateGroup  switchUser      pcapture
+    daemonize);
 %EXPORT_TAGS = (
     all => [
         qw(MAXCHILDREN      childrenCount   installChldHandler
             sigchld          pfork           ptranslateUser
-            ptranslateGroup  switchUser      pcapture)
+            ptranslateGroup  switchUser      pcapture
+            daemonize)
         ],
     pfork => [
         qw(MAXCHILDREN      childrenCount   installChldHandler
-            sigchld          pfork)
+            sigchld          pfork           daemonize)
         ],
         );
 
@@ -115,6 +117,46 @@
     $SIG{CHLD} = $osref;
 
     return 1;
+}
+
+sub daemonize () {
+
+    # Purpose:  Daemonizes process and disassociates with the terminal
+    # Returns:  True unless there are errors.
+    # Usage:    daemonize();
+
+    my ( $rv, $pid );
+
+    pdebug( 'entering', PDLEVEL1 );
+    pIn();
+
+    $pid = fork;
+
+    # Exit if we're the parent process
+    exit 0 if $pid;
+
+    if ( defined $pid ) {
+
+        # Fork was successful, close parent file descriptors
+        close STDIN;
+        close STDOUT;
+        close STDERR;
+
+        # Create a new process group
+        setsid();
+
+        $rv = 1;
+
+    } else {
+        Paranoid::ERROR =
+            pdebug( "Failed to daemonize process: $!", PDLEVEL1 );
+        $rv = 0;
+    }
+
+    pOut();
+    pdebug( "leaving w/rv: $rv", PDLEVEL1 );
+
+    return $rv;
 }
 
 sub pfork () {
@@ -366,11 +408,13 @@
 
 =head1 VERSION
 
-$Id: Process.pm,v 0.95 2010/04/15 23:23:28 acorliss Exp $
+$Id: Process.pm,v 0.99 2010/05/06 07:42:50 acorliss Exp $
 
 =head1 SYNOPSIS
 
   use Paranoid::Process;
+
+  $rv = daemonize();
 
   MAXCHILDREN = 100;
 
@@ -393,7 +437,8 @@
   all               All functions within this module
   pfork             All child management functions
 
-Only the function B<switchUser> is currently exported by default.
+Only the functions B<switchUser> and B<daemonize> are currently exported by 
+default.
 
 =head1 SUBROUTINES/METHODS
 
@@ -425,6 +470,14 @@
 This function decrements the child counter necessary for pfork's operation, as
 well as calling the user's signal handler with each child's PID and exit
 value.
+
+=head2 daemonize
+
+    $rv = daemonize();
+
+This function forks a child who closes all STD* filehandles and starts a new
+process group.  The parent exits cleanly.  If the fork fails for any reason it
+returns a false value.
 
 =head2 pfork
 

Modified: trunk/libparanoid-perl/t/02_input.t
URL: http://svn.debian.org/wsvn/pkg-perl/trunk/libparanoid-perl/t/02_input.t?rev=57726&op=diff
==============================================================================
--- trunk/libparanoid-perl/t/02_input.t (original)
+++ trunk/libparanoid-perl/t/02_input.t Sun May  9 05:04:47 2010
@@ -93,7 +93,7 @@
 push @all, @lines;
 is( sip( $f, \@lines, 1 ), 0, 'sip 11' );
 push @all, @lines;
-is( tail( $f, \@lines, -10 ), 0, 'tail 1' );
+ok( tail( $f, \@lines, -10 ), 'tail 1' );
 ok( closeFile($f), 'closeFile 1' );
 isnt( tail( $f, \@lines, -10 ), 0, 'tail 2' );
 ok( closeFile($f), 'closeFile 2' );
@@ -101,7 +101,7 @@
 open $fh, '>', $f or die "failed to open file: $!\n";
 close $fh;
 
-is( tail( $f, \@lines, -10 ), 0, 'tail 3' );
+ok( tail( $f, \@lines, -10 ), 'tail 3' );
 ok( closeFile($f), 'closeFile 3' );
 
 open $fh, '>', $f or die "failed to open file: $!\n";




More information about the Pkg-perl-cvs-commits mailing list