Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Proc::SafeExec(3)     User Contributed Perl Documentation    Proc::SafeExec(3)

NAME
       Proc::SafeExec -	Convenient utility for executing external commands in
       various ways.

SYNOPSIS
	       use Proc::SafeExec;
	       $SIG{"CHLD"} = "DEFAULT";  # Not	IGNORE,	so we can collect exit status.
	       my $command = Proc::SafeExec->new({
		       # Choose	just one of these.
		       "exec" => ["ls",	"-l", "myfile"],  # exec() after forking.
		       "fork" => 1,			  # Return undef in the	child after forking.

		       # Specify whether to capture each. Specify a file handle	ref to dup an existing
		       # one. Specify "new" to create a	new file handle, "default" or undef to keep
		       # the parent's descriptor, or "close" to	close it.
		       "stdin" => \*INPUT_PIPE,
		       "stdout"	=> \*OUTPUT_PIPE,
		       "stderr"	=> "new",

		       # Miscellaneous options.
		       "child_callback"	=> \&fref,  # Specify a	function to call in the	child after fork(), for	example, to drop privileges.
		       "debug" => 1,  #	Emit some information via warnings, such as the	command	to execute.
		       "no_autowait" =>	1,  # Don't automatically call $command->wait()	when $command is destroyed.
		       "real_arg0" => "/bin/ls",  # Specify the	actual file to execute.
		       "untaint_args" => 1,  # Untaint the arguments before exec'ing.
	       });
	       printf "Child's PID is %s\n", $command->child_pid() if $command->child_pid();

       The wait	method waits for the child to exit or checks whether it
       already exited:

	       $command->wait({
		       # Optional hash of options.
		       "no_close" => 1,	 # Don't close "new" file handles.
		       "nonblock" => 1,	 # Don't wait if the child hasn't exited (implies no_close).
	       });

       To communicate with the child:

	       # Perl doesn't understand <$command->stdout()>.
	       my $command_stdout = $command->stdout();
	       my $command_stderr = $command->stderr();

	       $line = <$command_stdout>;
	       $line = <$command_stderr>;
	       print {$command->stdin()} "mumble\n";

       To check	whether	the child exited yet:

	       print "Exit status: ", $command->exit_status(), "\n" if $command->wait({"nonblock" => 1});

       To wait until it	exits:

	       $command->wait();
	       print "Exit status: ", $command->exit_status(), "\n";

       A convenient quick tool for an alternative to $output = `@exec`:

	       ($output, $?) = Proc::SafeExec::backtick(@exec);

DESCRIPTION
       Proc::SafeExec provides an easy,	safe way to execute external programs.
       It replaces all of Perl's questionable ways of accomodating this,
       including system(), open() with a pipe, exec(), back-ticks, etc.	This
       module will never automatically invoke /bin/sh. This module is easy
       enough to use that /bin/sh should be unnecessary, even for complex
       pipelines.

       For all errors, this module dies	setting	$@.

       Errors from exec() in the child are reported gracefully to the parent.
       This means that if anything fails in the	child, the error is reported
       through $@ with die just	like any other error. This also	reports	$@ if
       child_callback dies when	it is called between fork() and	exec().	This
       is accomplished by passing $@ through an	extra pipe that's closed when
       exec succeeds. Note: A side-effect of this is $@	is stringified if it
       isn't a string.

CAVEATS
       When using an existing file handle by passing a reference for stdin,
       stdout, or stderr, new()	closes the previously open file	descriptor.
       This is to make sure, for example, that when setting up a pipeline the
       child process notices EOF on its	stdin. If you need this	file handle to
       stay open, dup it first.	For example:

	       open my $tmp_fh,	"<&", $original_fh or die "dup:	$!";
	       my $ls =	new Proc::SafeExec({"exec" => ["ls"], "stdout" => $tmp_fh});
	       # $tmp_fh is now	closed.

       By default, $command->wait() closes any new pipes opened	in the
       constructor.  This is to	prevent	a deadlock where the child is waiting
       to read or write	and the	parent is waiting for the child	to exit. Pass
       no_close	to $command->wait() to prevent this (see above). Also, by
       default the destructor calls $command->wait() if	child hasn't finished.
       This is to prevent zombie processes from	inadvertently accumulating. To
       prevent this, pass no_autowait to the constructor. The easiest way to
       wait for	the child is to	call the wait method, but if you need more
       control,	set no_autowait, then call child_pid to	get the	PID and	do the
       work yourself.

       This will emit a	warning	if the child exits with	a non-zero status, and
       the caller didn't inspect the exit status, and the caller didn't
       specify no_autowait (which may imply the	exit status might not be
       meaningful). It's bad practice not to inspect the exit status, and it's
       easy enough to quiet this warning if you	really don't want it by
       calling $command->exit_status() and discarding the result.

EXAMPLES
       It's easy to execute several programs to	form a pipeline. For the first
       program,	specify	"new" for stdout. Then execute the second one, and
       specify stdout from the first one for the stdin of the second one. For
       example,	here's how to write the	equivalent of system("ls | sort	>
       output.txt"):

	       open my $output_fh, ">",	"output.txt" or	die "output.txt: $!\n";
	       my $ls =	new Proc::SafeExec({"exec" => ["ls"], "stdout" => "new"});
	       my $sort	= new Proc::SafeExec({"exec" =>	["sort"], "stdin" => $ls->stdout(), "stdout" =>	$output_fh});
	       $ls->wait();
	       $sort->wait();
	       printf "ls exited with status %i\n", ($ls->exit_status()	>> 8);
	       printf "sort exited with	status %i\n", ($sort->exit_status() >> 8);

INSTALLATION
       This module has no dependencies besides Perl itself. Follow your
       favorite	standard installation procedure.

       To test the module, run the following command line:

	       $ perl -e 'use Proc::SafeExec; print Proc::SafeExec::test();'

VERSION	AND HISTORY
       o   Version 1.5,	released 2013-06-14. Fixed bug:	Open /dev/null for
	   STDIN STDOUT	STDERR instead of leaving closed when "close" is
	   specified. Also, recommend in doc to	set $SIG{"CHLD"} = "DEFAULT".

       o   Version 1.4,	released 2008-05-30. Added Proc::SafeExec::backtick()
	   function for	convenience. Fixed a couple minor bugs in error
	   handling (not security related). Invalidate $? after	reading	it so
	   callers must	fetch the exit status through $self->exit_status().

       o   Version 1.3,	released 2008-03-31. Added Proc::SafeExec::Queue. Emit
	   a warning when non-zero exit	status,	and the	caller didn't inspect
	   the exit status, and	the caller didn't specify no_autowait (which
	   may imply the exit status might not be meaningful).

       o   Version 1.2,	released 2008-01-22. Tweaked test() to handle temp
	   files correctly, addressing
	   https://rt.cpan.org/Ticket/Display.html?id=32458 .

       o   Version 1.1,	released 2008-01-09. Fixed obvious bug.

       o   Version 1.0,	released 2007-05-23.

SEE ALSO
       The source repository is	at git://git.devpit.org/Proc-SafeExec/

       See also	Proc::SafeExec::Queue.

MAINTAINER
       Leif Pedersen, <bilbo@hobbiton.org>

COPYRIGHT AND LICENSE
	This may be distributed	under the terms	below (BSD'ish)	or under the GPL.

	Copyright (c) 2007
	All Rights Reserved
	Meridian Environmental Technology, Inc.
	4324 University	Avenue,	Grand Forks, ND	58203
	http://meridian-enviro.com

	Redistribution and use in source and binary forms, with	or without
	modification, are permitted provided that the following	conditions are
	met:

	 1. Redistributions of source code must	retain the above copyright
	    notice, this list of conditions and	the following disclaimer.

	 2. Redistributions in binary form must	reproduce the above copyright
	    notice, this list of conditions and	the following disclaimer in the
	    documentation and/or other materials provided with the
	    distribution.

	THIS SOFTWARE IS PROVIDED BY AUTHORS AND CONTRIBUTORS "AS IS" AND ANY
	EXPRESS	OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
	IMPLIED	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A	PARTICULAR
	PURPOSE	ARE DISCLAIMED.	IN NO EVENT SHALL AUTHORS OR CONTRIBUTORS BE
	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
	BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY	OF LIABILITY,
	WHETHER	IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
	OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF	THIS SOFTWARE, EVEN IF
	ADVISED	OF THE POSSIBILITY OF SUCH DAMAGE.

perl v5.24.1			  2013-06-14		     Proc::SafeExec(3)

NAME | SYNOPSIS | DESCRIPTION | CAVEATS | EXAMPLES | INSTALLATION | VERSION AND HISTORY | SEE ALSO | MAINTAINER | COPYRIGHT AND LICENSE

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Proc::SafeExec&sektion=3&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help