From bd39076a1ca11987f1cbef34823ab5d09b082550 Mon Sep 17 00:00:00 2001 From: Raphael Hertzog Date: Fri, 15 Feb 2008 15:45:10 +0100 Subject: [PATCH] Dpkg::IPC: new module to handle common IPC * scripts/Dpkg/IPC.pm: New module handling IPC. Started with fork_and_exec() and wait_child(). STDIN/STDOUT of the child process can be easily redirected to a file or any other filehandle. --- debian/dpkg-dev.install | 1 + scripts/Dpkg/IPC.pm | 80 +++++++++++++++++++++++++++++++++++++++++ scripts/Makefile.am | 1 + scripts/po/POTFILES.in | 1 + 4 files changed, 83 insertions(+) create mode 100644 scripts/Dpkg/IPC.pm diff --git a/debian/dpkg-dev.install b/debian/dpkg-dev.install index b6eeb462..db4d00d6 100644 --- a/debian/dpkg-dev.install +++ b/debian/dpkg-dev.install @@ -71,6 +71,7 @@ usr/share/perl5/Dpkg/Changelog/Debian.pm usr/share/perl5/Dpkg/Deps.pm usr/share/perl5/Dpkg/ErrorHandling.pm usr/share/perl5/Dpkg/Fields.pm +usr/share/perl5/Dpkg/IPC.pm usr/share/perl5/Dpkg/Path.pm usr/share/perl5/Dpkg/Shlibs usr/share/perl5/Dpkg/Shlibs.pm diff --git a/scripts/Dpkg/IPC.pm b/scripts/Dpkg/IPC.pm new file mode 100644 index 00000000..090ecc97 --- /dev/null +++ b/scripts/Dpkg/IPC.pm @@ -0,0 +1,80 @@ +# Copyright 2008 Raphaël Hertzog + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +package Dpkg::IPC; + +use strict; +use warnings; + +use Dpkg::ErrorHandling qw(error syserr subprocerr); +use Dpkg::Gettext; + +use Exporter; +our @ISA = qw(Exporter); +our @EXPORT = qw(fork_and_exec wait_child); + +sub fork_and_exec { + my (%opts) = @_; + error("exec parameter is mandatory in fork_and_exec()") unless $opts{"exec"}; + my @prog; + if (ref($opts{"exec"}) =~ /ARRAY/) { + push @prog, @{$opts{"exec"}}; + } elsif (not ref($opts{"exec"})) { + push @prog, $opts{"exec"}; + } else { + error(_g("invalid exec parameter in fork_and_exec()")); + } + # Fork and exec + my $pid = fork(); + syserr(_g("fork for %s"), "@prog") unless defined $pid; + if (not $pid) { + # Redirect STDIN if needed + if ($opts{"from_file"}) { + open(STDIN, "<", $opts{"from_file"}) || + syserr(_g("cannot open %s"), $opts{"from_file"}); + } elsif ($opts{"from_handle"}) { + open(STDIN, "<&", $opts{"from_handle"}) || syserr(_g("reopen stdin")); + close($opts{"from_handle"}); # has been duped, can be closed + } + # Redirect STDOUT if needed + if ($opts{"to_file"}) { + open(STDOUT, ">", $opts{"to_file"}) || + syserr(_g("cannot write %s"), $opts{"to_file"}); + } elsif ($opts{"to_handle"}) { + open(STDOUT, ">&", $opts{"to_handle"}) || syserr(_g("reopen stdout")); + close($opts{"to_handle"}); # has been duped, can be closed + } + # Close some inherited filehandles + close($_) foreach (@{$opts{"close_in_child"}}); + # Execute the program + exec(@prog) or syserr(_g("exec %s"), "@prog"); + } + # Close handle that we can't use any more + close($opts{"from_handle"}) if exists $opts{"from_handle"}; + close($opts{"to_handle"}) if exists $opts{"to_handle"}; + + return $pid; +} + +sub wait_child { + my ($pid, %opts) = @_; + $opts{"cmdline"} ||= _g("child process"); + error(_g("no PID set, cannot wait end of process")) unless $pid; + $pid == waitpid($pid, 0) or syserr(_g("wait for %s"), $opts{"cmdline"}); + subprocerr($opts{"cmdline"}) if $?; +} + +1; diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 8d91d9df..4d79817b 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -95,6 +95,7 @@ nobase_dist_perllib_DATA = \ Dpkg/ErrorHandling.pm \ Dpkg/Fields.pm \ Dpkg/Gettext.pm \ + Dpkg/IPC.pm \ Dpkg/Path.pm \ Dpkg/Shlibs.pm \ Dpkg/Shlibs/Objdump.pm \ diff --git a/scripts/po/POTFILES.in b/scripts/po/POTFILES.in index 4a14b35f..240ff28f 100644 --- a/scripts/po/POTFILES.in +++ b/scripts/po/POTFILES.in @@ -22,6 +22,7 @@ scripts/Dpkg/Control.pm scripts/Dpkg/Deps.pm scripts/Dpkg/ErrorHandling.pm scripts/Dpkg/Fields.pm +scripts/Dpkg/IPC.pm scripts/Dpkg/Shlibs.pm scripts/Dpkg/Shlibs/Objdump.pm scripts/Dpkg/Shlibs/SymbolFile.pm -- 2.39.5