1POE::Wheel::Run(3)    User Contributed Perl Documentation   POE::Wheel::Run(3)
2
3
4

NAME

6       POE::Wheel::Run - event driven fork/exec with added value
7

SYNOPSIS

9         # Program may be scalar or \@array.
10         $program = '/usr/bin/cat -';
11         $program = [ '/usr/bin/cat', '-' ];
12
13         $wheel = POE::Wheel::Run->new(
14           # Set the program to execute, and optionally some parameters.
15           Program     => $program,
16           ProgramArgs => \@program_args,
17
18           # Define I/O events to emit.  Most are optional.
19           StdinEvent  => 'stdin',     # Flushed all data to the child's STDIN.
20           StdoutEvent => 'stdout',    # Received data from the child's STDOUT.
21           StderrEvent => 'stderr',    # Received data from the child's STDERR.
22           ErrorEvent  => 'oops',          # An I/O error occurred.
23           CloseEvent  => 'child_closed',  # Child closed all output handles.
24
25           # Optionally adjust the child process priority, user ID, and/or
26           # group ID.  You may need to be root to do this.
27           Priority    => +5,
28           User        => scalar(getpwnam 'nobody'),
29           Group       => scalar(getgrnam 'nobody'),
30
31           # Optionally specify different I/O formats.
32           StdinFilter  => POE::Filter::Line->new(),   # Child accepts input as lines.
33           StdoutFilter => POE::Filter::Stream->new(), # Child output is a stream.
34           StderrFilter => POE::Filter::Line->new(),   # Child errors are lines.
35
36           # Shorthand to set StdinFilter and StdoutFilter together.
37           StdioFilter => POE::Filter::Line->new(),    # Or some other filter.
38         );
39
40         # Information about the wheel and its process.
41         print "Unique wheel ID is  : ", $wheel->ID;
42         print "Wheel's child PID is: ", $wheel->PID;
43
44         # Send something to the child's STDIN.
45         $wheel->put( 'input for the child' );
46
47         # Kill the child.
48         $wheel->kill(9);  # TERM by default.
49

DESCRIPTION

51       Wheel::Run spawns child processes and establishes non-blocking, event
52       based communication with them.
53
54       Wheel::Run does not reap child processes.  For that, you need to regis‐
55       ter a SIGCHLD handler:
56
57         $kernel->sig(CHLD => "your_event");
58
59       The session will then receive your_event with details about $? when the
60       wheel's process exits and is reaped.  POE will reap child processes as
61       a side effect.
62
63       Another way to do it is to register $SIG{CHLD} = "IGNORE".  Use spar‐
64       ingly and with caution: This may clobber a handler that POE has already
65       registered for SIGCHLD.  Why does IGNORE work this way?  See the dis‐
66       cussion in perldoc perlipc.
67

PUBLIC METHODS

69       new LOTS_OF_STUFF
70         new() creates a new Run wheel.  If successful, the new wheel repre‐
71         sents a child process and the input, output and error pipes that
72         speak with it.
73
74         new() accepts lots of stuff.  Each parameter is name/value pair.
75
76         Conduit
77           "Conduit" describes how Wheel::Run should talk with the child
78           process.  By default it will try various forms of inter-process
79           communication to build a pipe between the parent and child pro‐
80           cesses.  If a particular method is preferred, it can be set to
81           "pipe", "socketpair", or "inet".  It may also be set to "pty" if
82           the child process should have its own pseudo tty.  Setting it to
83           "pty-pipe" gives the child process a stdin and stdout pseudo-tty,
84           but keeps stderr as a pipe, rather than merging stdout and stderr
85           as with "pty".
86
87           The reasons to define this parameter would be if you want to use
88           "pty", if the default pipe type doesn't work properly on your sys‐
89           tem, or the default pipe type's performance is poor.
90
91           Pty conduits require the IO::Pty module.
92
93         Winsize
94           "Winsize" is only valid for "Conduit = "pty"" and used to set the
95           window size of the pty device.
96
97           The window size is given as an array reference.  The first element
98           is the number of lines, the second the number of columns. The third
99           and the fourth arguments are optional and specify the X and Y
100           dimensions in pixels.
101
102         CloseOnCall
103           "CloseOnCall" emulates the close-on-exec feature for child pro‐
104           cesses which are not started by exec().  When it is set to 1, all
105           open file handles whose descriptors are greater than $^F are closed
106           in the child process.  This is only effective when POE::Wheel::Run
107           is called with a code reference for its Program parameter.
108
109             CloseOnCall => 1,
110             Program => \&some_function,
111
112           CloseOnCall defaults to 0 (off) to remain compatible with existing
113           programs.
114
115           For more details, please the discussion of $^F in perlvar.
116
117         StdioDriver
118         StdinDriver
119         StdoutDriver
120         StderrDriver
121           These parameters change the drivers for Wheel::Run.  The default
122           drivers are created internally with "<POE::Driver::SysRW-"new()>>.
123
124           "StdioDriver" changes both "StdinDriver" and "StdoutDriver" at the
125           same time.
126
127         CloseEvent
128         ErrorEvent
129         StdinEvent
130         StdoutEvent
131         StderrEvent
132           See "EVENTS AND PARAMETERS" below for a more detailed description
133           of these events and their parameters.
134
135           "CloseEvent" contains the name of an event to emit when the child
136           process closes all its output handles.  This is a consistent noti‐
137           fication that the child will not be sending any more output.  It
138           does not, however, signal that the client process has stopped
139           accepting input.
140
141           "ErrorEvent" contains the name of an event to emit if something
142           fails.  It is optional and if omitted, the wheel will not notify
143           its session if any errors occur.
144
145           Wheel::Run requires at least one of the following three events:
146
147           "StdinEvent" contains the name of an event that Wheel::Run emits
148           whenever everything queued by its put() method has been flushed to
149           the child's STDIN handle.
150
151           "StdoutEvent" and "StderrEvent" contain names of events that
152           Wheel::Run emits whenever the child process writes something to its
153           STDOUT or STDERR handles, respectively.
154
155         StdioFilter
156         StdinFilter
157         StdoutFilter
158         StderrFilter
159           "StdioFilter" contains an instance of a POE::Filter subclass.  The
160           filter describes how the child process performs input and output.
161           "Filter" will be used to describe the child's stdin and stdout
162           methods.  If stderr is also to be used, StderrFilter will need to
163           be specified separately.
164
165           "Filter" is optional.  If left blank, it will default to an
166           instance of "POE::Filter::Line-"new(Literal => "\n");>
167
168           "StdinFilter" and "StdoutFilter" can be used instead of or in addi‐
169           tion to "StdioFilter".  They will override the default filter's
170           selection in situations where a process' input and output are in
171           different formats.
172
173         Group
174           "Group" contains a numerical group ID that the child process should
175           run at.  This may not be meaningful on systems that have no concept
176           of group IDs.  The current process may need to run as root in order
177           to change group IDs.  Mileage varies considerably.
178
179         NoSetSid
180           When true, "NoSetSid" disables setsid() in the child process.  By
181           default, setsid() is called to execute the child process in a sepa‐
182           rate Unix session.
183
184         Priority
185           "Priority" contains an offset from the current process's priority.
186           The child will be executed at the current priority plus the offset.
187           The priority offset may be negative, but the current process may
188           need to be running as root for that to work.
189
190         Program
191           "Program" is the program to exec() once pipes and fork have been
192           set up.  "Program"'s type determines how the program will be run.
193
194           If "Program" holds a scalar, it will be executed as exec($scalar).
195           Shell metacharacters will be expanded in this form.
196
197           If "Program" holds an array reference, it will executed as
198           exec(@$array).  This form of exec() doesn't expand shell metachar‐
199           acters.
200
201           If "Program" holds a code reference, it will be called in the
202           forked child process, and then the child will exit.  This allows
203           Wheel::Run to fork off bits of long-running code which can accept
204           STDIN input and pass responses to STDOUT and/or STDERR.  Note, how‐
205           ever, that POE's services are effectively disabled in the child
206           process.
207
208           perlfunc has more information about exec() and the different ways
209           to call it.
210
211           Note: Do not call exit() explicitly when executing a subroutine.
212           POE::Wheel::Run takes special care to avoid object destructors and
213           END blocks in the child process, and calling exit() will thwart
214           that.  You may see "POE::Kernel's run() method was never called."
215           or worse.
216
217         ProgramArgs => ARRAY
218           If specified, "ProgramArgs" should refer to a list of parameters
219           for the program being run.
220
221             my @parameters = qw(foo bar baz);  # will be passed to Program
222             ProgramArgs => \@parameters;
223
224       event EVENT_TYPE => EVENT_NAME, ...
225         event() changes the event that Wheel::Run emits when a certain type
226         of event occurs.  "EVENT_TYPE" may be one of the event parameters in
227         Wheel::Run's constructor.
228
229           $wheel->event( StdinEvent  => 'new-stdin-event',
230                          StdoutEvent => 'new-stdout-event',
231                        );
232
233       put LIST
234         put() queues a LIST of different inputs for the child process.  They
235         will be flushed asynchronously once the current state returns.  Each
236         item in the LIST is processed according to the "StdinFilter".
237
238       get_stdin_filter
239       get_stdout_filter
240       get_stderr_filter
241         Get "StdinFilter", "StdoutFilter", or "StderrFilter" respectively.
242
243       set_stdio_filter FILTER_REFERENCE
244         Set "StdinFilter" and "StdoutFilter" at once.
245
246       set_stdin_filter FILTER_REFERENCE
247       set_stdout_filter FILTER_REFERENCE
248       set_stderr_filter FILTER_REFERENCE
249         Set "StdinFilter", "StdoutFilter", or "StderrFilter" respectively.
250
251       pause_stdout
252       pause_stderr
253       resume_stdout
254       resume_stderr
255         Pause or resume "StdoutEvent" or "StderrEvent" events.  By using
256         these methods a session can control the flow of Stdout and Stderr
257         events coming in from this child process.
258
259       shutdown_stdin
260         Closes the child process' STDIN and stops the wheel from reporting
261         StdinEvent.  It is extremely useful for running utilities that expect
262         to receive EOF on their standard inputs before they respond.
263
264       ID
265         Returns the wheel's unique ID, which is not the same as the child
266         process' ID.  Every event generated by Wheel::Run includes a wheel ID
267         so that it can be matched up with its generator.  This lets a single
268         session manage several wheels without becoming confused about which
269         one generated what event.
270
271       PID
272         Returns the child process' ID.  It's useful for matching up to
273         SIGCHLD events, which include child process IDs as well, so that
274         wheels can be destroyed properly when children exit.
275
276       kill SIGNAL
277         Sends a signal to the child process.  It's useful for processes which
278         tend to be reluctant to exit when their terminals are closed.
279
280         The kill() method will send SIGTERM if SIGNAL is undef or omitted.
281
282       get_driver_out_messages
283       get_driver_out_octets
284         Return driver statistics.
285

EVENTS AND PARAMETERS

287       CloseEvent
288         CloseEvent contains the name of the event Wheel::Run emits whenever a
289         child process has closed all its output handles.  It signifies that
290         the child will not be sending more information.  In addition to the
291         usual POE parameters, each CloseEvent comes with one of its own:
292
293         "ARG0" contains the wheel's unique ID.  This can be used to keep sev‐
294         eral child processes separate when they're managed by the same ses‐
295         sion.
296
297         A sample close event handler:
298
299           sub close_state {
300             my ($heap, $wheel_id) = @_[HEAP, ARG0];
301
302             my $child = delete $heap->{child}->{$wheel_id};
303             print "Child ", $child->PID, " has finished.\n";
304           }
305
306       ErrorEvent
307         ErrorEvent contains the name of an event that Wheel::Run emits when‐
308         ever an error occurs.  Every error event comes with four parameters:
309
310         "ARG0" contains the name of the operation that failed.  It may be
311         'read', 'write', 'fork', 'exec' or the name of some other function or
312         task.  The actual values aren't yet defined.  Note: This is not nec‐
313         essarily a function name.
314
315         "ARG1" and "ARG2" hold numeric and string values for $!, respec‐
316         tively.  "$!" will eq "" for read error 0 (child process closed STD‐
317         OUT or STDERR).
318
319         "ARG3" contains the wheel's unique ID.
320
321         "ARG4" contains the name of the child filehandle that has the error.
322         It may be "STDIN", "STDOUT", or "STDERR".  The sense of "ARG0" will
323         be the opposite of what you might normally expect for these handles.
324         For example, Wheel::Run will report a "read" error on "STDOUT"
325         because it tried to read data from that handle.
326
327         A sample error event handler:
328
329           sub error_state {
330             my ($operation, $errnum, $errstr, $wheel_id) = @_[ARG0..ARG3];
331             $errstr = "remote end closed" if $operation eq "read" and !$errnum;
332             warn "Wheel $wheel_id generated $operation error $errnum: $errstr\n";
333           }
334
335       StdinEvent
336         StdinEvent contains the name of an event that Wheel::Run emits when‐
337         ever everything queued by its put() method has been flushed to the
338         child's STDIN handle.
339
340         StdinEvent's "ARG0" parameter contains its wheel's unique ID.
341
342       StdoutEvent
343       StderrEvent
344         StdoutEvent and StderrEvent contain names for events that Wheel::Run
345         emits whenever the child process generates new output.  StdoutEvent
346         contains information the child wrote to its STDOUT handle, and Stder‐
347         rEvent includes whatever arrived from the child's STDERR handle.
348
349         Both of these events come with two parameters.  "ARG0" contains the
350         information that the child wrote.  "ARG1" holds the wheel's unique
351         ID.
352
353           sub stdout_state {
354             my ($heap, $input, $wheel_id) = @_[HEAP, ARG0, ARG1];
355             print "Child process in wheel $wheel_id wrote to STDOUT: $input\n";
356           }
357
358           sub stderr_state {
359             my ($heap, $input, $wheel_id) = @_[HEAP, ARG0, ARG1];
360             print "Child process in wheel $wheel_id wrote to STDERR: $input\n";
361           }
362

TIPS AND TRICKS

364       One common task is scrubbing a child process' environment.  This
365       amounts to clearing the contents of %ENV and setting it up with some
366       known, secure values.
367
368       Environment scrubbing is easy when the child process is running a sub‐
369       routine, but it's not so easy---or at least not as intuitive---when
370       executing external programs.
371
372       The way we do it is to run a small subroutine in the child process that
373       performs the exec() call for us.
374
375         Program => \&exec_with_scrubbed_env,
376
377         sub exec_with_scrubbed_env {
378           delete @ENV{keys @ENV};
379           $ENV{PATH} = "/bin";
380           exec(@program_and_args);
381         }
382
383       That deletes everything from the environment, sets a simple, secure
384       PATH, and executes a program with its arguments.
385

SEE ALSO

387       POE::Wheel.
388
389       The SEE ALSO section in POE contains a table of contents covering the
390       entire POE distribution.
391

BUGS

393       Wheel::Run's constructor doesn't emit proper events when it fails.
394       Instead, it just dies, carps or croaks.
395
396       Filter changing hasn't been implemented yet.  Let the author know if
397       it's needed.  Better yet, patch the file based on the code in
398       Wheel::ReadWrite.
399
400       Priority is a delta; there's no way to set it directly to some value.
401
402       User must be specified by UID.  It would be nice to support login
403       names.
404
405       Group must be specified by GID.  It would be nice to support group
406       names.
407

AUTHORS & COPYRIGHTS

409       Please see POE for more information about authors and contributors.
410
411
412
413perl v5.8.8                       2006-09-01                POE::Wheel::Run(3)
Impressum