1POE::Wheel::Run(3) User Contributed Perl Documentation POE::Wheel::Run(3)
2
3
4
6 POE::Wheel::Run - portably run blocking code and programs in
7 subprocesses
8
10 #!/usr/bin/perl
11
12 use warnings;
13 use strict;
14
15 use POE qw( Wheel::Run );
16
17 POE::Session->create(
18 inline_states => {
19 _start => \&on_start,
20 got_child_stdout => \&on_child_stdout,
21 got_child_stderr => \&on_child_stderr,
22 got_child_close => \&on_child_close,
23 got_child_signal => \&on_child_signal,
24 }
25 );
26
27 POE::Kernel->run();
28 exit 0;
29
30 sub on_start {
31 my $child = POE::Wheel::Run->new(
32 Program => [ "/bin/ls", "-1", "/" ],
33 StdoutEvent => "got_child_stdout",
34 StderrEvent => "got_child_stderr",
35 CloseEvent => "got_child_close",
36 );
37
38 $_[KERNEL]->sig_child($child->PID, "got_child_signal");
39
40 # Wheel events include the wheel's ID.
41 $_[HEAP]{children_by_wid}{$child->ID} = $child;
42
43 # Signal events include the process ID.
44 $_[HEAP]{children_by_pid}{$child->PID} = $child;
45
46 print(
47 "Child pid ", $child->PID,
48 " started as wheel ", $child->ID, ".\n"
49 );
50 }
51
52 # Wheel event, including the wheel's ID.
53 sub on_child_stdout {
54 my ($stdout_line, $wheel_id) = @_[ARG0, ARG1];
55 my $child = $_[HEAP]{children_by_wid}{$wheel_id};
56 print "pid ", $child->PID, " STDOUT: $stdout_line\n";
57 }
58
59 # Wheel event, including the wheel's ID.
60 sub on_child_stderr {
61 my ($stderr_line, $wheel_id) = @_[ARG0, ARG1];
62 my $child = $_[HEAP]{children_by_wid}{$wheel_id};
63 print "pid ", $child->PID, " STDERR: $stderr_line\n";
64 }
65
66 # Wheel event, including the wheel's ID.
67 sub on_child_close {
68 my $wheel_id = $_[ARG0];
69 my $child = delete $_[HEAP]{children_by_wid}{$wheel_id};
70
71 # May have been reaped by on_child_signal().
72 unless (defined $child) {
73 print "wid $wheel_id closed all pipes.\n";
74 return;
75 }
76
77 print "pid ", $child->PID, " closed all pipes.\n";
78 delete $_[HEAP]{children_by_pid}{$child->PID};
79 }
80
81 sub on_child_signal {
82 print "pid $_[ARG1] exited with status $_[ARG2].\n";
83 my $child = delete $_[HEAP]{children_by_pid}{$_[ARG1]};
84
85 # May have been reaped by on_child_close().
86 return unless defined $child;
87
88 delete $_[HEAP]{children_by_wid}{$child->ID};
89 }
90
92 POE::Wheel::Run executes a program or block of code in a subprocess,
93 created the usual way: using fork(). The parent process may exchange
94 information with the child over the child's STDIN, STDOUT and STDERR
95 filehandles.
96
97 In the parent process, the POE::Wheel::Run object represents the child
98 process. It has methods such as PID() and kill() to query and manage
99 the child process.
100
101 POE::Wheel::Run's put() method sends data to the child's STDIN. Child
102 output on STDOUT and STDERR may be dispatched as events within the
103 parent, if requested.
104
105 POE::Wheel::Run can also notify the parent when the child has closed
106 its output filehandles. Some programs remain active, but they close
107 their output filehandles to indicate they are done writing.
108
109 A more reliable way to detect child exit is to use POE::Kernel's
110 sig_child() method to wait for the wheel's process to be reaped. It is
111 in fact vital to use sig_child() in all circumstances since without it,
112 POE will not try to reap child processes.
113
114 Failing to use sig_child() has in the past led to wedged machines.
115 Long-running programs have leaked processes, eventually consuming all
116 available slots in the process table and requiring reboots.
117
118 Because process leaks are so severe, POE::Kernel will check for this
119 condition on exit and display a notice if it finds that processes are
120 leaking. Developers should heed these warnings.
121
122 POE::Wheel::Run communicates with the child process in a line-based
123 fashion by default. Programs may override this by specifying some
124 other POE::Filter object in "StdinFilter", "StdoutFilter",
125 "StdioFilter" and/or "StderrFilter".
126
128 Constructor
129 POE::Wheel subclasses tend to perform a lot of setup so that they run
130 lighter and faster. POE::Wheel::Run's constructor is no exception.
131
132 new
133
134 new() creates and returns a new POE::Wheel::Run object. If it's
135 successful, the object will represent a child process with certain
136 specified qualities. It also provides an OO- and event-based interface
137 for asynchronously interacting with the process.
138
139 Conduit
140
141 Conduit specifies the inter-process communications mechanism that will
142 be used to pass data between the parent and child process. Conduit may
143 be one of "pipe", "socketpair", "inet", "pty", or "pty-pipe".
144 POE::Wheel::Run will use the most appropriate Conduit for the run-time
145 (not the compile-time) operating system, but this varies from one OS to
146 the next.
147
148 Internally, POE::Wheel::Run passes the Conduit type to
149 POE::Pipe::OneWay and POE::Pipe::TwoWay. These helper classes were
150 created to make IPC portable and reusable. They do not require the
151 rest of POE.
152
153 Three Conduit types use pipes or pipelike inter-process communication:
154 "pipe", "socketpair" and "inet". They determine whether the internal
155 IPC uses pipe(), socketpair() or Internet sockets. These Conduit
156 values are passed through to POE::Pipe::OneWay or POE::Pipe::TwoWay
157 internally.
158
159 The "pty" conduit type runs the child process under a pseudo-tty, which
160 is created by IO::Pty. Pseudo-ttys (ptys) convince child processes
161 that they are interacting with terminals rather than pipes. This may
162 be used to trick programs like ssh into believing it's secure to prompt
163 for a password, although passphraseless identities might be better for
164 that.
165
166 The "pty" conduit cannot separate STDERR from STDOUT, but the "pty-
167 pipe" mode can.
168
169 The "pty-pipe" conduit uses a pty for STDIN and STDOUT and a one-way
170 pipe for STDERR. The additional pipe keeps STDERR output separate from
171 STDOUT.
172
173 The IO::Pty module is only loaded if "pty" or "pty-pipe" is used. It's
174 not a dependency until it's actually needed.
175
176 Winsize
177
178 Winsize sets the child process' terminal size. Its value should be an
179 arrayref with four elements. The first two elements must be the number
180 of lines and columns for the child's terminal window, respectively.
181 The second pair of elements describe the terminal's X and Y dimensions
182 in pixels. If the last pair is missing, they will be calculated from
183 the lines and columns using a 9x16 cell size.
184
185 $_[HEAP]{child} = POE::Wheel::Run->new(
186 # ... among other things ...
187 Winsize => [ 25, 80, 720, 400 ],
188 );
189
190 Winsize is only valid for conduits that use pseudo-ttys: "pty" and
191 "pty-pipe". Other conduits don't simulate terminals, so they don't
192 have window sizes.
193
194 Winsize defaults to the parent process' window size, assuming the
195 parent process has a terminal to query.
196
197 CloseOnCall
198
199 CloseOnCall, when true, turns on close-on-exec emulation for
200 subprocesses that don't actually call exec(). These would be instances
201 when the child is running a block of code rather than executing an
202 external program. For example:
203
204 $_[HEAP]{child} = POE::Wheel::Run->new(
205 # ... among other things ...
206 CloseOnCall => 1,
207 Program => \&some_function,
208 );
209
210 CloseOnCall is off (0) by default.
211
212 CloseOnCall works by closing all file descriptors greater than $^F in
213 the child process before calling the application's code. For more
214 details, please the discussion of $^F in perlvar.
215
216 StdioDriver
217
218 StdioDriver specifies a single POE::Driver object to be used for both
219 STDIN and STDOUT. It's equivalent to setting "StdinDriver" and
220 "StdoutDriver" to the same POE::Driver object.
221
222 POE::Wheel::Run will create and use a POE::Driver::SysRW driver of one
223 isn't specified. This is by far the most common use case, so it's the
224 default.
225
226 StdinDriver
227
228 "StdinDriver" sets the POE::Driver used to write to the child process'
229 STDIN IPC conduit. It is almost never needed. Omitting it will allow
230 POE::Wheel::Run to use an internally created POE::Driver::SysRW object.
231
232 StdoutDriver
233
234 "StdoutDriver" sets the POE::Driver object that will be used to read
235 from the child process' STDOUT conduit. It's almost never needed. If
236 omitted, POE::Wheel::Run will internally create and use a
237 POE::Driver::SysRW object.
238
239 StderrDriver
240
241 "StderrDriver" sets the driver that will be used to read from the child
242 process' STDERR conduit. As with "StdoutDriver", it's almost always
243 preferable to let POE::Wheel::Run instantiate its own driver.
244
245 CloseEvent
246
247 CloseEvent contains the name of an event that the wheel will emit when
248 the child process closes its last open output handle. This is a
249 consistent notification that the child is done sending output. Please
250 note that it does not signal when the child process has exited.
251 Programs should use sig_child() to detect that.
252
253 While it is impossible for ErrorEvent or StdoutEvent to happen after
254 CloseEvent, there is no such guarantee for CHLD, which may happen
255 before or after CloseEvent.
256
257 In addition to the usual POE parameters, each CloseEvent comes with one
258 of its own:
259
260 "ARG0" contains the wheel's unique ID. This can be used to keep
261 several child processes separate when they're managed by the same
262 session.
263
264 A sample close event handler:
265
266 sub close_state {
267 my ($heap, $wheel_id) = @_[HEAP, ARG0];
268
269 my $child = delete $heap->{child}->{$wheel_id};
270 print "Child ", $child->PID, " has finished.\n";
271 }
272
273 ErrorEvent
274
275 ErrorEvent contains the name of an event to emit if something fails.
276 It is optional; if omitted, the wheel will not notify its session if
277 any errors occur. However, POE::Wheel::Run->new() will still throw an
278 exception if it fails.
279
280 "ARG0" contains the name of the operation that failed. It may be
281 'read', 'write', 'fork', 'exec' or the name of some other function or
282 task. The actual values aren't yet defined. They will probably not
283 correspond so neatly to Perl builtin function names.
284
285 "ARG1" and "ARG2" hold numeric and string values for $!, respectively.
286 "$!" will eq "" for read error 0 (child process closed the file
287 handle).
288
289 "ARG3" contains the wheel's unique ID.
290
291 "ARG4" contains the name of the child filehandle that has the error.
292 It may be "STDIN", "STDOUT", or "STDERR". The sense of "ARG0" will be
293 the opposite of what you might normally expect for these handles. For
294 example, POE::Wheel::Run will report a "read" error on "STDOUT" because
295 it tried to read data from the child's STDOUT handle.
296
297 A sample error event handler:
298
299 sub error_state {
300 my ($operation, $errnum, $errstr, $wheel_id) = @_[ARG0..ARG3];
301 $errstr = "remote end closed" if $operation eq "read" and !$errnum;
302 warn "Wheel $wheel_id generated $operation error $errnum: $errstr\n";
303 }
304
305 Note that unless you deactivate the signal pipe, you might also see
306 "EIO" (5) error during read operations.
307
308 StdinEvent
309
310 StdinEvent contains the name of an event that Wheel::Run emits whenever
311 everything queued by its put() method has been flushed to the child's
312 STDIN handle. It is the equivalent to POE::Wheel::ReadWrite's
313 FlushedEvent.
314
315 StdinEvent comes with only one additional parameter: "ARG0" contains
316 the unique ID for the wheel that sent the event.
317
318 StdoutEvent
319
320 StdoutEvent contains the name of an event that Wheel::Run emits
321 whenever the child process writes something to its STDOUT filehandle.
322 In other words, whatever the child prints to STDOUT, the parent
323 receives a StdoutEvent---provided that the child prints something
324 compatible with the parent's StdoutFilter.
325
326 StdoutEvent comes with two parameters. "ARG0" contains the information
327 that the child wrote to STDOUT. "ARG1" holds the unique ID of the
328 wheel that read the output.
329
330 sub stdout_state {
331 my ($heap, $input, $wheel_id) = @_[HEAP, ARG0, ARG1];
332 print "Child process in wheel $wheel_id wrote to STDOUT: $input\n";
333 }
334
335 StderrEvent
336
337 StderrEvent behaves exactly as StdoutEvent, except for data the child
338 process writes to its STDERR filehandle.
339
340 StderrEvent comes with two parameters. "ARG0" contains the information
341 that the child wrote to STDERR. "ARG1" holds the unique ID of the
342 wheel that read the output.
343
344 sub stderr_state {
345 my ($heap, $input, $wheel_id) = @_[HEAP, ARG0, ARG1];
346 print "Child process in wheel $wheel_id wrote to STDERR: $input\n";
347 }
348
349 RedirectStdout
350
351 This is a filehandle or filename to which standard output will be
352 redirected. It is an error to use this option together with
353 StdoutEvent. This is useful in case your program needs to have standard
354 I/O, but do not actually care for its contents to be visible to the
355 parent.
356
357 RedirectStderr
358
359 Just like RedirectStdout, but with standard error. It is an error to
360 use this together with StderrEvent
361
362 RedirectStdin
363
364 This is a filehandle or filename which the child process will use as
365 its standard input. It is an error to use this option with StdinEvent
366
367 RedirectOutput
368
369 This will redirect stderr and stdout to the same filehandle. This is
370 equivalent to do doing something like
371
372 $ something > /path/to/output 2>&1
373
374 in bourne shell.
375
376 NoStdin
377
378 While output filehandles will be closed if there are no events to be
379 received on them, stdin is open by default - because lack of an event
380 handler does not necessarily mean there is no desired input stream.
381 This option explicitly disables the creation of an IPC stdin conduit.
382
383 StdioFilter
384
385 StdioFilter, if used, must contain an instance of a POE::Filter
386 subclass. This filter describes how the parent will format put() data
387 for the child's STDIN, and how the parent will parse the child's
388 STDOUT.
389
390 If STDERR will also be parsed, then a separate StderrFilter will also
391 be needed.
392
393 StdioFilter defaults to a POE::Filter::Line instance, but only if both
394 StdinFilter and StdoutFilter are not specified. If either StdinFilter
395 or StdoutFilter is used, then StdioFilter is illegal.
396
397 StdinFilter
398
399 StdinFilter may be used to specify a particular STDIN serializer that
400 is different from the STDOUT parser. If specified, it conflicts with
401 StdioFilter. StdinFilter's value, if specified, must be an instance of
402 a POE::Filter subclass.
403
404 Without a StdinEvent, StdinFilter is illegal.
405
406 StdoutFilter
407
408 StdoutFilter may be used to specify a particular STDOUT parser that is
409 different from the STDIN serializer. If specified, it conflicts with
410 StdioFilter. StdoutFilter's value, if specified, must be an instance
411 of a POE::Filter subclass.
412
413 Without a StdoutEvent, StdoutFilter is illegal.
414
415 StderrFilter
416
417 StderrFilter may be used to specify a filter for a child process'
418 STDERR output. If omitted, POE::Wheel::Run will create and use its own
419 POE::Filter::Line instance, but only if a StderrEvent is specified.
420
421 Without a StderrEvent, StderrFilter is illegal.
422
423 Group
424
425 Group contains a numeric group ID that the child process should run
426 within. By default, the child process will run in the same group as
427 the parent.
428
429 Group is not fully portable. It may not work on systems that have no
430 concept of user groups. Also, the parent process may need to run with
431 elevated privileges for the child to be able to change groups.
432
433 User
434
435 User contains a numeric user ID that should own the child process. By
436 default, the child process will run as the same user as the parent.
437
438 User is not fully portable. It may not work on systems that have no
439 concept of users. Also, the parent process may need to run with
440 elevated privileges for the child to be able to change users.
441
442 NoSetSid
443
444 When true, NoSetSid disables setsid() in the child process. By
445 default, the child process calls setsid() is called so that it may
446 execute in a separate UNIX session.
447
448 NoSetPgrp
449
450 When true, NoSetPgrp disables setprgp() in the child process. By
451 default, the child process calls setpgrp() to change its process group,
452 if the OS supports that.
453
454 setsid() is used instead of setpgrp() if Conduit is pty or pty-pipe.
455 See "NoSetSid".
456
457 Priority
458
459 Priority adjusts the child process' niceness or priority level,
460 depending on which (if any) the underlying OS supports. Priority
461 contains a numeric offset which will be added to the parent's priority
462 to determine the child's.
463
464 The priority offset may be negative, which in UNIX represents a higher
465 priority. However UNIX requires elevated privileges to increase a
466 process' priority.
467
468 Program
469
470 Program specifies the program to exec() or the block of code to run in
471 the child process. Program's type is significant.
472
473 If Program holds a scalar, its value will be executed as
474 exec($program). Shell metacharacters are significant, per exec(SCALAR)
475 semantics.
476
477 If Program holds an array reference, it will executed as
478 exec(@$program). As per exec(ARRAY), shell metacharacters will not be
479 significant.
480
481 If Program holds a code reference, that code will be called in the
482 child process. This mode allows POE::Wheel::Run to execute long-
483 running internal code asynchronously, while the usual modes execute
484 external programs. The child process will exit after that code is
485 finished, in such a way as to avoid DESTROY and END block execution.
486 See "Coderef Execution Side Effects" for more details.
487
488 perlfunc has more information about exec() and the different ways to
489 call it.
490
491 Please avoid calling exit() explicitly when executing a subroutine.
492 The child process inherits all objects from the parent, including ones
493 that may perform side effects. POE::Wheel::Run takes special care to
494 avoid object destructors and END blocks in the child process, but
495 calling exit() will trigger them.
496
497 ProgramArgs
498
499 If specified, ProgramArgs should refer to a list of parameters for the
500 program being run.
501
502 my @parameters = qw(foo bar baz); # will be passed to Program
503 ProgramArgs => \@parameters;
504
505 event EVENT_TYPE => EVENT_NAME, ...
506 event() allows programs to change the events that Wheel::Run emits when
507 certain activities occurs. EVENT_TYPE may be one of the event
508 parameters described in POE::Wheel::Run's constructor.
509
510 This example changes the events that $wheel emits for STDIN flushing
511 and STDOUT activity:
512
513 $wheel->event(
514 StdinEvent => 'new-stdin-event',
515 StdoutEvent => 'new-stdout-event',
516 );
517
518 Undefined EVENT_NAMEs disable events.
519
520 put RECORDS
521 put() queues up a list of RECORDS that will be sent to the child
522 process' STDIN filehandle. These records will first be serialized
523 according to the wheel's StdinFilter. The serialized RECORDS will be
524 flushed asynchronously once the current event handler returns.
525
526 get_stdin_filter
527 get_stind_filter() returns the POE::Filter object currently being used
528 to serialize put() records for the child's STDIN filehandle. The
529 return object may be used according to its own interface.
530
531 get_stdout_filter
532 get_stdout_filter() returns the POE::Filter object currently being used
533 to parse what the child process writes to STDOUT.
534
535 get_stderr_filter
536 get_stderr_filter() returns the POE::Filter object currently being used
537 to parse what the child process writes to STDERR.
538
539 set_stdio_filter FILTER_OBJECT
540 Set StdinFilter and StdoutFilter to the same new FILTER_OBJECT.
541 Unparsed STDOUT data will be parsed later by the new FILTER_OBJECT.
542 However, data already put() will remain serialized by the old filter.
543
544 set_stdin_filter FILTER_OBJECT
545 Set StdinFilter to a new FILTER_OBJECT. Data already put() will remain
546 serialized by the old filter.
547
548 set_stdout_filter FILTER_OBJECT
549 Set StdoutFilter to a new FILTER_OBJECT. Unparsed STDOUT data will be
550 parsed later by the new FILTER_OBJECT.
551
552 set_stderr_filter FILTER_OBJECT
553 Set StderrFilter to a new FILTER_OBJECT. Unparsed STDERR data will be
554 parsed later by the new FILTER_OBJECT.
555
556 pause_stdout
557 Pause reading of STDOUT from the child. The child process may block if
558 the STDOUT IPC conduit fills up. Reading may be resumed with
559 resume_stdout().
560
561 pause_stderr
562 Pause reading of STDERR from the child. The child process may block if
563 the STDERR IPC conduit fills up. Reading may be resumed with
564 resume_stderr().
565
566 resume_stdout
567 Resume reading from the child's STDOUT filehandle. This is only
568 meaningful if pause_stdout() has been called and remains in effect.
569
570 resume_stderr
571 Resume reading from the child's STDERR filehandle. This is only
572 meaningful if pause_stderr() has been called and remains in effect.
573
574 shutdown_stdin
575 shutdown_stdin() closes the child process' STDIN and stops the wheel
576 from reporting StdinEvent. It is extremely useful for running
577 utilities that expect to receive EOF on STDIN before they respond.
578
579 ID
580 ID() returns the wheel's unique ID. Every event generated by a
581 POE::Wheel::Run object includes a wheel ID so that it can be matched to
582 the wheel that emitted it. This lets a single session manage several
583 wheels without becoming confused about which one generated what event.
584
585 ID() is not the same as PID().
586
587 PID
588 PID() returns the process ID for the child represented by the
589 POE::Wheel::Run object. It's often used as a parameter to sig_child().
590
591 PID() is not the same as ID().
592
593 kill SIGNAL
594 POE::Wheel::Run's kill() method sends a SIGNAL to the child process the
595 object represents. kill() is often used to force a reluctant program
596 to terminate. SIGNAL is one of the operating signal names present in
597 %SIG.
598
599 kill() returns the number of processes successfully signaled: 1 on
600 success, or 0 on failure, since the POE::Wheel::Run object only affects
601 at most a single process.
602
603 kill() sends SIGTERM if SIGNAL is undef or omitted.
604
605 get_driver_out_messages
606 get_driver_out_messages() returns the number of put() records remaining
607 in whole or in part in POE::Wheel::Run's POE::Driver output queue. It
608 is often used to tell whether the wheel has more input for the child
609 process.
610
611 In most cases, StdinEvent may be used to trigger activity when all data
612 has been sent to the child process.
613
614 get_driver_out_octets
615 get_driver_out_octets() returns the number of serialized octets
616 remaining in POE::Wheel::Run's POE::Driver output queue. It is often
617 used to tell whether the wheel has more input for the child process.
618
620 MSWin32 Support
621 In the past POE::Wheel::Run did not support MSWin32 and users had to
622 use custom work-arounds. Then Chris Williams ( BINGOS ) arrived and
623 saved the day with his POE::Wheel::Run::Win32 module. After some
624 testing, it was decided to merge the win32 code into POE::Wheel::Run.
625 Everyone was happy!
626
627 However, after some investigation Apocalypse ( APOCAL ) found out that
628 in some situations it still didn't behave properly. The root cause was
629 that the win32 code path in POE::Wheel::Run didn't exit cleanly. This
630 means DESTROY and END blocks got executed! After talking with more
631 people, the solution was not pretty.
632
633 The problem is that there is no equivalent of POSIX::_exit() for
634 MSWin32. Hopefully, in a future version of Perl this can be fixed! In
635 the meantime, POE::Wheel::Run will use CORE::kill() to terminate the
636 child. However, this comes with a caveat: you will leak around 1KB per
637 exec. The code has been improved so the chance of this happening has
638 been reduced.
639
640 As of now the most reliable way to trigger this is to exec an invalid
641 binary. The definition of "invalid binary" depends on different things,
642 but what it means is that Win32::Job->spawn() failed to run. This will
643 force POE::Wheel::Run to use the workaround to exit the child. If this
644 happens, a very big warning will be printed to the STDERR of the child
645 and the parent process will receive it.
646
647 If you are a Perl MSWin32 hacker, PLEASE help us with this situation!
648 Go read rt.cpan.org bug #56417 and talk with us/p5p to see where you
649 can contribute.
650
651 Thanks again for your patience as we continue to improve
652 POE::Wheel::Run on MSWin32!
653
654 kill() and ClosedEvent on Windows
655
656 Windows will often fail to report EOF on pipes when subprocesses are
657 killed. The work-around is to catch the signal in the subprocess, and
658 exit normally:
659
660 my $child = POE::Wheel::Run->new(
661 Program => sub {
662 $SIG{INT} = sub { exit };
663 ...;
664 },
665 ...,
666 );
667
668 Be sure to kill() the subprocess using the same signal that it catches
669 and exits upon. Remember, not all signals can be caught by user code.
670
671 $child->kill("INT");
672
673 Execution Environment
674 It's common to scrub a child process' environment, so that only
675 required, secure values exist. This amounts to clearing the contents
676 of %ENV and repopulating it.
677
678 Environment scrubbing is easy when the child process is running a
679 subroutine, but it's not so easy---or at least not as intuitive---when
680 executing external programs.
681
682 The way we do it is to run a small subroutine in the child process that
683 performs the exec() call for us.
684
685 Program => \&exec_with_scrubbed_env,
686
687 sub exec_with_scrubbed_env {
688 delete @ENV{keys @ENV};
689 $ENV{PATH} = "/bin";
690 exec(@program_and_args);
691 }
692
693 That deletes everything from the environment and sets a simple, secure
694 PATH before executing a program.
695
696 Coderef Execution Side Effects
697 The child process is created by fork(), which duplicates the parent
698 process including a copy of POE::Kernel, all running Session instances,
699 events in the queue, watchers, open filehandles, and so on.
700
701 When executing an external program, the UNIX exec() call immediately
702 replaces the copy of the parent with a completely new program.
703
704 When executing internal coderefs, however, we must preserve the code
705 and any memory it might reference. This leads to some potential side
706 effects.
707
708 DESTROY and END Blocks Run Twice
709
710 Objects that were created in the parent process are copied into the
711 child. When the child exits normally, any DESTROY and END blocks are
712 executed there. Later, when the parent exits, they may run again.
713
714 POE::Wheel::Run takes steps to avoid running DESTROY and END blocks in
715 the child process. It uses POSIX::_exit() to bypass them. If that
716 fails, it may even kill() itself.
717
718 If an application needs to exit explicitly, for example to return an
719 error code to the parent process, then please use POSIX::_exit() rather
720 than Perl's core exit().
721
722 POE::Kernel's run() method was never called
723
724 This warning is displayed from POE::Kernel's DESTROY method. It's a
725 side effect of calling exit() in a child process that was started
726 before "POE::Kernel->run()" could be called. The child process
727 receives a copy of POE::Kernel where run() wasn't called, even if it
728 was called later in the parent process.
729
730 The most direct solution is to call POSIX::_exit() rather than exit().
731 This will bypass POE::Kernel's DESTROY, and the message it emits.
732
733 Running POE::Kernel in the Child
734
735 Calling "POE::Kernel->run()" in the child process effectively resumes
736 the copy of the parent process. This is rarely (if ever) desired.
737
738 More commonly, an application wants to run an entirely new POE::Kernel
739 instance in the child process. This is supported by first stop()ping
740 the copied instance, starting one or more new sessions, and calling
741 run() again. For example:
742
743 Program => sub {
744 # Wipe the existing POE::Kernel clean.
745 $poe_kernel->stop();
746
747 # Start a new session, or more.
748 POE::Session->create(
749 ...
750 );
751
752 # Run the new sessions.
753 POE::Kernel->run();
754 }
755
756 Strange things are bound to happen if the program does not call "stop"
757 in POE::Kernel before "run" in POE::Kernel. However this is vaguely
758 supported in case it's the right thing to do at the time.
759
761 POE::Wheel describes wheels in general.
762
763 The SEE ALSO section in POE contains a table of contents covering the
764 entire POE distribution.
765
767 POE::Wheel::Run's constructor should emit proper events when it fails.
768 Instead, it just dies, carps or croaks. This isn't necessarily bad; a
769 program can trap the death in new() and move on.
770
771 Priority is a delta, not an absolute niceness value.
772
773 It might be nice to specify User by name rather than just UID.
774
775 It might be nice to specify Group by name rather than just GID.
776
777 POE::Pipe::OneWay and Two::Way don't require the rest of POE. They
778 should be spun off into a separate distribution for everyone to enjoy.
779
780 If StdinFilter and StdoutFilter seem backwards, remember that it's the
781 filters for the child process. StdinFilter is the one that dictates
782 what the child receives on STDIN. StdoutFilter tells the parent how to
783 parse the child's STDOUT.
784
786 Please see POE for more information about authors and contributors.
787
788
789
790perl v5.32.1 2021-01-27 POE::Wheel::Run(3)