1package POE::Wheel::Run;
2
3use strict;
4
5use vars qw($VERSION @ISA);
6$VERSION = '1.368'; # NOTE - Should be #.### (three decimal places)
7
8use Carp qw(carp croak);
9use POSIX qw(
10  sysconf setsid _SC_OPEN_MAX ECHO ICANON IEXTEN ISIG BRKINT ICRNL
11  INPCK ISTRIP IXON CSIZE PARENB OPOST TCSANOW
12);
13
14use POE qw( Wheel Pipe::TwoWay Pipe::OneWay Driver::SysRW Filter::Line );
15push @ISA, qw(POE::Wheel);
16
17# http://rt.cpan.org/Ticket/Display.html?id=50068
18# Avoid using these constants in Windows' subprocesses (actually
19# interpreter threads).  Reported in the above ticket to avoid a
20# memory leak.
21my ($STD_INPUT_HANDLE, $STD_OUTPUT_HANDLE, $STD_ERROR_HANDLE);
22
23BEGIN {
24  die "$^O does not support fork()\n" if $^O eq 'MacOS';
25
26  local $SIG{'__DIE__'} = 'DEFAULT';
27  eval    { require IO::Pty; };
28  if ($@) {
29    eval '
30      sub PTY_AVAILABLE () { 0 }
31      sub TIOCSWINSZ_AVAILABLE () { 0 }
32    ';
33  }
34  else {
35    IO::Pty->import();
36    eval 'sub PTY_AVAILABLE () { 1 }';
37
38    eval { require IO::Tty; };
39    if ($@) {
40      eval 'sub TIOCSWINSZ_AVAILABLE () { 0 }';
41    }
42    else {
43      IO::Tty->import('TIOCSWINSZ');
44      eval 'sub TIOCSWINSZ_AVAILABLE () { 1 }';
45    }
46  }
47
48  if (POE::Kernel::RUNNING_IN_HELL) {
49    eval    { require Win32::Console; Win32::Console->import() };
50    if ($@) { die "Win32::Console needed for POE::Wheel::Run on $^O:\n$@" }
51
52    eval    {
53      require Win32API::File;
54      Win32API::File->import("FdGetOsFHandle");
55    };
56    if ($@) { die "Win32API::File needed for POE::Wheel::Run on $^O:\n$@" }
57
58    eval    { require Win32::Process; Win32::Process->import() };
59    if ($@) { die "Win32::Process needed for POE::Wheel::Run on $^O:\n$@" }
60
61    eval    { require Win32::Job; Win32::Job->import() };
62    if ($@) { die "Win32::Job needed for POE::Wheel::Run on $^O:\n$@" }
63
64    eval    { require Win32; Win32->import() };
65    if ($@) { die "Win32.pm needed for POE::Wheel::Run on $^O:\n$@" }
66
67    $STD_INPUT_HANDLE  = STD_INPUT_HANDLE();
68    $STD_OUTPUT_HANDLE = STD_OUTPUT_HANDLE();
69    $STD_ERROR_HANDLE  = STD_ERROR_HANDLE();
70  }
71
72  # Determine the most file descriptors we can use.
73  my $max_open_fds;
74  eval {
75    $max_open_fds = sysconf(_SC_OPEN_MAX);
76  };
77  $max_open_fds = 1024 unless $max_open_fds;
78  eval "sub MAX_OPEN_FDS () { $max_open_fds }";
79  die if $@;
80};
81
82# Offsets into $self.
83sub UNIQUE_ID     () {  0 }
84sub ERROR_EVENT   () {  1 }
85sub CLOSE_EVENT   () {  2 }
86sub PROGRAM       () {  3 }
87sub CHILD_PID     () {  4 }
88sub CONDUIT_TYPE  () {  5 }
89sub IS_ACTIVE     () {  6 }
90sub CLOSE_ON_CALL () {  7 }
91sub STDIO_TYPE    () {  8 }
92
93sub HANDLE_STDIN  () {  9 }
94sub FILTER_STDIN  () { 10 }
95sub DRIVER_STDIN  () { 11 }
96sub EVENT_STDIN   () { 12 }
97sub STATE_STDIN   () { 13 }
98sub OCTETS_STDIN  () { 14 }
99
100sub HANDLE_STDOUT () { 15 }
101sub FILTER_STDOUT () { 16 }
102sub DRIVER_STDOUT () { 17 }
103sub EVENT_STDOUT  () { 18 }
104sub STATE_STDOUT  () { 19 }
105
106sub HANDLE_STDERR () { 20 }
107sub FILTER_STDERR () { 21 }
108sub DRIVER_STDERR () { 22 }
109sub EVENT_STDERR  () { 23 }
110sub STATE_STDERR  () { 24 }
111
112sub MSWIN32_GROUP_PID () { 25 }
113
114# Used to work around a bug in older perl versions.
115sub CRIMSON_SCOPE_HACK ($) { 0 }
116
117#------------------------------------------------------------------------------
118
119sub new {
120  my $type = shift;
121  croak "$type needs an even number of parameters" if @_ & 1;
122  my %params = @_;
123
124  croak "wheels no longer require a kernel reference as their first parameter"
125    if @_ and ref($_[0]) eq 'POE::Kernel';
126
127  croak "$type requires a working Kernel" unless defined $poe_kernel;
128
129  my $program = delete $params{Program};
130  croak "$type needs a Program parameter" unless defined $program;
131
132  my $prog_args = delete $params{ProgramArgs};
133  $prog_args = [] unless defined $prog_args;
134  croak "ProgramArgs must be an ARRAY reference"
135    unless ref($prog_args) eq "ARRAY";
136
137  my $priority_delta = delete $params{Priority};
138  $priority_delta = 0 unless defined $priority_delta;
139
140  my $close_on_call = delete $params{CloseOnCall};
141  $close_on_call = 0 unless defined $close_on_call;
142
143  my $user_id  = delete $params{User};
144  my $group_id = delete $params{Group};
145
146  # The following $stdio_type is new.  $conduit is kept around for now
147  # to preserve the logic of the rest of the module.  This change
148  # allows a Session using POE::Wheel::Run to define the type of pipe
149  # to be created for stdin and stdout.  Read the POD on Conduit.
150  # However, the documentation lies, because if Conduit is undefined,
151  # $stdio_type is set to undefined (so the default pipe type provided
152  # by POE::Pipe::TwoWay will be used). Otherwise, $stdio_type
153  # determines what type of pipe Pipe:TwoWay creates unless it's
154  # 'pty'.
155
156  my $conduit = delete $params{Conduit};
157  my $stdio_type;
158  if (defined $conduit) {
159    croak "$type\'s Conduit type ($conduit) is unknown" if (
160      $conduit ne 'pipe' and
161      $conduit ne 'pty'  and
162      $conduit ne 'pty-pipe' and
163      $conduit ne 'socketpair' and
164      $conduit ne 'inet'
165    );
166    unless ($conduit =~ /^pty(-pipe)?$/) {
167      $stdio_type = $conduit;
168      $conduit = "pipe";
169    }
170  }
171  else {
172    $conduit = "pipe";
173  }
174
175  my $winsize = delete $params{Winsize};
176
177  if ($winsize) {
178    carp "winsize can only be specified for a Conduit of type pty"
179      if $conduit !~ /^pty(-pipe)?$/ and $winsize;
180
181    if( 'ARRAY' eq ref $winsize and 2==@$winsize ) {
182        # Standard VGA cell in 9x16
183        # http://en.wikipedia.org/wiki/VGA-compatible_text_mode#Fonts
184        $winsize->[2] = $winsize->[1]*9;
185        $winsize->[3] = $winsize->[0]*16;
186    }
187    carp "winsize must be a 4 element arrayref" unless ref($winsize) eq 'ARRAY'
188      and scalar @$winsize == 4;
189
190    carp "winsize only works when IO::Tty::TIOCSWINSZ is"
191      unless TIOCSWINSZ_AVAILABLE;
192  }
193
194  my $stdin_event  = delete $params{StdinEvent};
195  my $stdout_event = delete $params{StdoutEvent};
196  my $stderr_event = delete $params{StderrEvent};
197
198  if ($conduit eq 'pty' and defined $stderr_event) {
199    carp "ignoring StderrEvent with pty conduit";
200    undef $stderr_event;
201  }
202
203  #croak "$type needs at least one of StdinEvent, StdoutEvent or StderrEvent"
204  #  unless (defined($stdin_event) or defined($stdout_event) or defined ($stderr_event));
205
206  my $stdio_driver  = delete $params{StdioDriver}  || POE::Driver::SysRW->new();
207  my $stdin_driver  = delete $params{StdinDriver}  || $stdio_driver;
208  my $stdout_driver = delete $params{StdoutDriver} || $stdio_driver;
209  my $stderr_driver = delete $params{StderrDriver} || POE::Driver::SysRW->new();
210
211  my $stdio_filter  = delete $params{Filter};
212  my $stdin_filter  = delete $params{StdinFilter};
213  my $stdout_filter = delete $params{StdoutFilter};
214  my $stderr_filter = delete $params{StderrFilter};
215
216  #For optional redirection...
217  my $redir_err     = delete $params{RedirectStderr};
218  my $redir_out     = delete $params{RedirectStdout};
219  my $redir_in      = delete $params{RedirectStdin};
220  my $redir_output  = delete $params{RedirectOutput};
221
222  my $no_stdin      = delete $params{NoStdin};
223
224  if(defined $redir_output) {
225    $redir_out = $redir_err = $redir_output;
226  }
227
228  #Sanity check. We can't wait for redirected filehandles
229  if( (defined $redir_in and defined $stdin_event) ||
230     (defined $redir_out and defined $stdout_event) ||
231     (defined $redir_err and defined $stderr_event) ) {
232    croak("Redirect* and *Event stdio options are mutually exclusive");
233  }
234
235  if (defined $stdio_filter) {
236    croak "Filter and StdioFilter cannot be used together"
237      if defined $params{StdioFilter};
238    croak "Replace deprecated Filter with StdioFilter and StderrFilter"
239      if defined $stderr_event and not defined $stderr_filter;
240    carp "Filter is deprecated.  Please try StdioFilter and/or StderrFilter";
241  }
242  else {
243    $stdio_filter = delete $params{StdioFilter};
244  }
245  $stdio_filter = POE::Filter::Line->new(Literal => "\n")
246    unless defined $stdio_filter;
247
248  $stdin_filter  = $stdio_filter unless defined $stdin_filter;
249  $stdout_filter = $stdio_filter unless defined $stdout_filter;
250
251  if ($conduit eq 'pty' and defined $stderr_filter) {
252    carp "ignoring StderrFilter with pty conduit";
253    undef $stderr_filter;
254  }
255  else {
256    $stderr_filter = POE::Filter::Line->new(Literal => "\n")
257      unless defined $stderr_filter;
258  }
259
260  croak "$type needs either StdioFilter or StdinFilter when using StdinEvent"
261    if defined($stdin_event) and not defined($stdin_filter);
262  croak "$type needs either StdioFilter or StdoutFilter when using StdoutEvent"
263    if defined($stdout_event) and not defined($stdout_filter);
264  croak "$type needs a StderrFilter when using StderrEvent"
265    if defined($stderr_event) and not defined($stderr_filter);
266
267  my $error_event = delete $params{ErrorEvent};
268  my $close_event = delete $params{CloseEvent};
269
270  my $no_setsid = delete $params{NoSetSid};
271  my $no_setpgrp = delete $params{NoSetPgrp};
272
273  # Make sure the user didn't pass in parameters we're not aware of.
274  if (scalar keys %params) {
275    carp(
276      "unknown parameters in $type constructor call: ",
277      join(', ', sort keys %params)
278    );
279  }
280
281  # Did the user mangle stdio?
282  unless (ref($program) eq 'CODE') {
283    croak "Someone has closed or moved STDIN... exec() won't find it"
284      unless defined fileno(STDIN) && fileno(STDIN) == 0;
285    croak "Someone has closed or moved STDOUT... exec() won't find it"
286      unless tied(*STDOUT) || defined fileno(STDOUT) && fileno(STDOUT) == 1;
287    croak "Someone has closed or moved STDERR... exec() won't find it"
288      unless tied(*STDERR) || defined fileno(STDERR) && fileno(STDERR) == 2;
289  }
290
291  my (
292    $stdin_read, $stdout_write, $stdout_read, $stdin_write,
293    $stderr_read, $stderr_write,
294  );
295
296  _filespec_to_fh(\$stdin_read, "<", $redir_in);
297  if($redir_output) {
298    _filespec_to_fh(\$stdout_write, ">", $redir_output);
299    _filespec_to_fh(\$stderr_write, ">", $stdout_write);
300  } else {
301    _filespec_to_fh(\$stdout_write, ">", $redir_out);
302    _filespec_to_fh(\$stderr_write, ">", $redir_err);
303  }
304
305  # Create a semaphore pipe.  This is used so that the parent doesn't
306  # begin listening until the child's stdio has been set up.
307
308  my ($sem_pipe_read, $sem_pipe_write) = POE::Pipe::OneWay->new();
309  croak "could not create semaphore pipe: $!" unless defined $sem_pipe_read;
310
311  # Use IO::Pty if requested.  IO::Pty turns on autoflush for us.
312
313  if(defined $stdout_event
314     or defined $stdin_event
315     or defined $stderr_event
316     or (!$no_stdin))
317  #Bypass all the conduit handling if the user does not care for child I/O
318  {
319    if ($conduit =~ /^pty(-pipe)?$/) {
320      croak "IO::Pty is not available" unless PTY_AVAILABLE;
321
322      if(defined $redir_err or defined $redir_in or defined $redir_out) {
323        croak "Redirection with pty conduit is unsupported";
324      }
325
326      $stdin_write = $stdout_read = IO::Pty->new();
327      croak "could not create master pty: $!" unless defined $stdout_read;
328      if ($conduit eq "pty-pipe") {
329        ($stderr_read, $stderr_write) = POE::Pipe::OneWay->new();
330        croak "could not make stderr pipes: $!"
331          unless defined $stderr_read and defined $stderr_write;
332      }
333    }
334
335    # Use pipes otherwise.
336    elsif ($conduit eq 'pipe') {
337      # We make more pipes than strictly necessary in case someone wants
338      # to turn some on later.  Uses a TwoWay pipe for STDIN/STDOUT and
339      # a OneWay pipe for STDERR.  This may save 2 filehandles if
340      # socketpair() is available and no other $stdio_type is selected.
341
342      foreach (
343        [\$redir_out, \$stdout_read, \$stdout_write, $stdout_event, "stdout"],
344        [\$redir_err, \$stderr_read, \$stderr_write, $stderr_event, "stderr"],
345        [\$redir_in, \$stdin_read, \$stdin_write, $stdin_event, "stdin"]
346        ) {
347        my ($redir_ref,$rfd_ref,$wfd_ref,$evname, $prettyprint) = @$_;
348        if(defined $evname && (!defined $$redir_ref)) {
349          ($$rfd_ref,$$wfd_ref) = POE::Pipe::OneWay->new();
350          croak "could not make $prettyprint pipe: $!"
351            unless defined $$rfd_ref and defined $$wfd_ref;
352        }
353      }
354      unless (defined($redir_in) or $no_stdin) {
355        ($stdin_read, $stdin_write) = POE::Pipe::OneWay->new();
356        croak "could not make stdin pipe $!"
357          unless defined $stdin_write and defined $stdin_read;
358      }
359    }
360
361    # Sanity check.
362    else {
363      croak "unknown conduit type $conduit";
364    }
365  }
366
367  # Block signals until safe
368  my $must_unmask;
369  if( $poe_kernel->can( '_data_sig_mask_all' ) ) {
370    $poe_kernel->_data_sig_mask_all;
371    $must_unmask = 1;
372  }
373
374  # Fork!  Woo-hoo!
375  my $pid = fork;
376
377  # Child.  Parent side continues after this block.
378  unless ($pid) {
379    # removed the croak because it wasn't "safe" RT#56417
380    #croak "couldn't fork: $!" unless defined $pid;
381    # ANY OTHER DIE/CROAK/EXIT/WHATEVER in the child MUST use the helper!
382    __PACKAGE__->_warn_and_exit_child( "couldn't fork: $!", int( $! ) )
383      unless defined $pid;
384
385    # Stdio should not be tied.  Resolves rt.cpan.org ticket 1648.
386    if (tied *STDIN) {
387      carp "Cannot redirect out of tied STDIN.  Untying it";
388      untie *STDIN;
389    }
390
391    if (tied *STDOUT) {
392      carp "Cannot redirect into tied STDOUT.  Untying it";
393      untie *STDOUT;
394    }
395
396    if (tied *STDERR) {
397      carp "Cannot redirect into tied STDERR.  Untying it";
398      untie *STDERR;
399    }
400
401    # If running pty, we delay the slave side creation 'til after
402    # doing the necessary bits to become our own [unix] session.
403    if ($conduit =~ /^pty(-pipe)?$/) {
404
405      # Become a new unix session.
406      # Program 19.3, APITUE.  W. Richard Stevens built my hot rod.
407      eval 'setsid()' unless $no_setsid;
408
409      # Acquire a controlling terminal.  Program 19.3, APITUE.
410      $stdin_write->make_slave_controlling_terminal();
411
412      # Open the slave side of the pty.
413      $stdin_read = $stdout_write = $stdin_write->slave();
414      __PACKAGE__->_warn_and_exit_child( "could not create slave pty: $!", int( $! ) )
415        unless defined $stdin_read;
416
417      # For a simple pty conduit, stderr is wedged into stdout.
418      $stderr_write = $stdout_write if $conduit eq 'pty';
419
420      # Put the pty conduit (slave side) into "raw" or "cbreak" mode,
421      # per APITUE 19.4 and 11.10.
422      $stdin_read->set_raw();
423
424      if (TIOCSWINSZ_AVAILABLE) {
425        if ($winsize) {
426          ioctl($stdin_read, TIOCSWINSZ, pack('vvvv', @$winsize));
427        }
428      }
429      else {
430        # Set the pty conduit (slave side) window size to our window
431        # size.  APITUE 19.4 and 19.5.
432
433        eval { $stdin_read->clone_winsize_from(\*STDIN) } if -T STDIN;
434      }
435    }
436    else {
437      # TODO - Can this be block eval?  Or a do{} block?
438      eval 'setpgrp(0,0)' unless $no_setpgrp;
439    }
440
441    # Reset all signals in the child process.  POE's own handlers are
442    # silly to keep around in the child process since POE won't be
443    # using them.
444    my @safe_signals = $poe_kernel->_data_sig_get_safe_signals();
445    @SIG{@safe_signals} = ("DEFAULT") x @safe_signals;
446    $poe_kernel->_data_sig_unmask_all if $must_unmask;
447
448    # TODO How to pass events to the parent process?  Maybe over a
449    # expedited (OOB) filehandle.
450
451    # Fix the child process' priority.  Don't bother doing this if it
452    # wasn't requested.  Can't emit events on failure because we're in
453    # a separate process, so just fail quietly.
454
455    if ($priority_delta) {
456      eval {
457        if (defined(my $priority = getpriority(0, $$))) {
458          unless (setpriority(0, $$, $priority + $priority_delta)) {
459            # TODO can't set child priority
460          }
461        }
462        else {
463          # TODO can't get child priority
464        }
465      };
466      if ($@) {
467        # TODO can't get child priority
468      }
469    }
470
471    # Fix the group ID.  TODO Add getgrnam so group IDs can be
472    # specified by name.  TODO Warn if not superuser to begin with.
473    if (defined $group_id) {
474      $( = $) = $group_id;
475    }
476
477    # Fix the user ID.  TODO Add getpwnam so user IDs can be specified
478    # by name.  TODO Warn if not superuser to begin with.
479    if (defined $user_id) {
480      $< = $> = $user_id;
481    }
482
483    # Close what the child won't need.
484    close $stdin_write if defined $stdin_write;
485    close $stdout_read if defined $stdout_read;
486    close $stderr_read if defined $stderr_read;
487
488    if (POE::Kernel::RUNNING_IN_HELL) {
489      __PACKAGE__->_redirect_child_stdio_in_hell(
490        $stdin_read, $stdout_write, $stderr_write
491      );
492    }
493
494    else {
495      __PACKAGE__->_redirect_child_stdio_sanely(
496        $stdin_read, $stdout_write, $stderr_write
497      );
498    }
499
500    # Make STDOUT and/or STDERR auto-flush.
501    select STDERR;  $| = 1;
502    select STDOUT;  $| = 1;
503
504    # The child doesn't need to read from the semaphore pipe.
505    $sem_pipe_read = undef;
506
507    # Run Perl code.  This is fairly consistent across most systems.
508
509    if (ref($program) eq 'CODE') {
510
511      # Tell the parent that the stdio has been set up.
512      print $sem_pipe_write "go\n";
513      close $sem_pipe_write;
514
515      # Close any close-on-exec file descriptors.  Except STDIN,
516      # STDOUT, and STDERR, of course.
517      if ($close_on_call) {
518        for (0..MAX_OPEN_FDS-1) {
519          next if fileno(STDIN)  == $_;
520          next if fileno(STDOUT) == $_;
521          next if fileno(STDERR) == $_;
522          POSIX::close($_);
523        }
524      }
525
526      # TODO what if the program tries to exit? It needs to use
527      # our _exit_child_any_way_we_can handler...
528      # Should we replace CORE::exit? CORE::die too? blahhhhhh
529      # We've documented that users should not do it, but who knows!
530      eval { $program->(@$prog_args) };
531
532      my $exitval;
533      if ($@) {
534        chomp $@;
535        warn "$@\n";
536        $exitval = -1;
537      }
538
539      __PACKAGE__->_exit_child_any_way_we_can( $exitval || 0 );
540    }
541
542    # Execute an external program.  This gets weird.
543
544    # Windows! What I do for you!
545    __PACKAGE__->_exec_in_hell(
546      $close_on_call, $sem_pipe_write, $program, $prog_args
547    ) if POE::Kernel::RUNNING_IN_HELL;
548
549    # Everybody else seems sane.
550    # Tell the parent that the stdio has been set up.
551    print $sem_pipe_write "go\n";
552    close $sem_pipe_write;
553
554    # exec(ARRAY)
555    if (ref($program) eq 'ARRAY') {
556      exec(@$program, @$prog_args)
557         or __PACKAGE__->_warn_and_exit_child(
558           "can't exec (@$program) in child pid $$: $!", int( $! ) );
559    }
560
561    # exec(SCALAR)
562    exec(join(" ", $program, @$prog_args))
563      or __PACKAGE__->_warn_and_exit_child(
564        "can't exec ($program) in child pid $$: $!", int( $! ) );
565  }
566
567  # Parent here.  Close what the parent won't need.
568
569  defined($stdin_read)   and close $stdin_read;
570  defined($stdout_write) and close $stdout_write;
571  defined($stderr_write) and close $stderr_write;
572
573
574
575  # Also close any slave ptys
576  $stdout_read->close_slave() if (
577    defined $stdout_read and ref($stdout_read) eq 'IO::Pty'
578  );
579
580  $stderr_read->close_slave() if (
581    defined $stderr_read and ref($stderr_read) eq 'IO::Pty'
582  );
583
584  my $active_count = 0;
585  $active_count++ if $stdout_event and $stdout_read;
586  $active_count++ if $stderr_event and $stderr_read;
587
588  my $self = bless [
589    &POE::Wheel::allocate_wheel_id(),  # UNIQUE_ID
590    $error_event,   # ERROR_EVENT
591    $close_event,   # CLOSE_EVENT
592    $program,       # PROGRAM
593    $pid,           # CHILD_PID
594    $conduit,       # CONDUIT_TYPE
595    $active_count,  # IS_ACTIVE
596    $close_on_call, # CLOSE_ON_CALL
597    $stdio_type,    # STDIO_TYPE
598    # STDIN
599    $stdin_write,   # HANDLE_STDIN
600    $stdin_filter,  # FILTER_STDIN
601    $stdin_driver,  # DRIVER_STDIN
602    $stdin_event,   # EVENT_STDIN
603    undef,          # STATE_STDIN
604    0,              # OCTETS_STDIN
605    # STDOUT
606    $stdout_read,   # HANDLE_STDOUT
607    $stdout_filter, # FILTER_STDOUT
608    $stdout_driver, # DRIVER_STDOUT
609    $stdout_event,  # EVENT_STDOUT
610    undef,          # STATE_STDOUT
611    # STDERR
612    $stderr_read,   # HANDLE_STDERR
613    $stderr_filter, # FILTER_STDERR
614    $stderr_driver, # DRIVER_STDERR
615    $stderr_event,  # EVENT_STDERR
616    undef,          # STATE_STDERR
617    undef,          # MSWIN32_GROUP_PID
618  ], $type;
619
620  # PG- I suspect <> might need PIPE
621  $poe_kernel->_data_sig_unmask_all if $must_unmask;
622
623  # Wait here while the child sets itself up.
624  $sem_pipe_write = undef;
625  {
626    local $/ = "\n";  # TODO - Needed?
627    my $chldout = <$sem_pipe_read>;
628    chomp $chldout;
629    $self->[MSWIN32_GROUP_PID] = $chldout if $chldout ne 'go';
630  }
631  close $sem_pipe_read;
632
633  $self->_define_stdin_flusher() if defined $stdin_write;
634  $self->_define_stdout_reader() if defined $stdout_read;
635  $self->_define_stderr_reader() if defined $stderr_read;
636
637  return $self;
638}
639
640#------------------------------------------------------------------------------
641# Define the internal state that will flush output to the child
642# process' STDIN pipe.
643
644sub _define_stdin_flusher {
645  my $self = shift;
646
647  # Read-only members.  If any of these change, then the write state
648  # is invalidated and needs to be redefined.
649  my $unique_id    = $self->[UNIQUE_ID];
650  my $driver       = $self->[DRIVER_STDIN];
651  my $error_event  = \$self->[ERROR_EVENT];
652  my $close_event  = \$self->[CLOSE_EVENT];
653  my $stdin_filter = $self->[FILTER_STDIN];
654  my $stdin_event  = \$self->[EVENT_STDIN];
655  my $is_active    = \$self->[IS_ACTIVE];
656
657  # Read/write members.  These are done by reference, to avoid pushing
658  # $self into the anonymous sub.  Extra copies of $self are bad and
659  # can prevent wheels from destructing properly.
660  my $stdin_octets = \$self->[OCTETS_STDIN];
661
662  # Register the select-write handler.
663  $poe_kernel->state(
664    $self->[STATE_STDIN] = ref($self) . "($unique_id) -> select stdin",
665    sub {                             # prevents SEGV
666      0 && CRIMSON_SCOPE_HACK('<');
667                                      # subroutine starts here
668      my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
669
670      $$stdin_octets = $driver->flush($handle);
671
672      # When you can't write, nothing else matters.
673      if ($!) {
674        $$error_event && $k->call(
675          $me, $$error_event,
676          'write', ($!+0), $!, $unique_id, "STDIN"
677        );
678        $k->select_write($handle);
679      }
680
681      # Could write, or perhaps couldn't but only because the
682      # filehandle's buffer is choked.
683      else {
684
685        # All chunks written; fire off a "flushed" event.
686        unless ($$stdin_octets) {
687          $k->select_pause_write($handle);
688          $$stdin_event && $k->call($me, $$stdin_event, $unique_id);
689        }
690      }
691    }
692  );
693
694  $poe_kernel->select_write($self->[HANDLE_STDIN], $self->[STATE_STDIN]);
695
696  # Pause the write select immediately, unless output is pending.
697  $poe_kernel->select_pause_write($self->[HANDLE_STDIN])
698    unless ($self->[OCTETS_STDIN]);
699}
700
701#------------------------------------------------------------------------------
702# Define the internal state that will read input from the child
703# process' STDOUT pipe.  This is virtually identical to
704# _define_stderr_reader, but they aren't implemented as a common
705# function for speed reasons.
706
707sub _define_stdout_reader {
708  my $self = shift;
709
710  # Can't do anything if we don't have a handle.
711  return unless defined $self->[HANDLE_STDOUT];
712
713  # No event?  Unregister the handler and leave.
714  my $stdout_event  = \$self->[EVENT_STDOUT];
715  unless ($$stdout_event) {
716    $poe_kernel->select_read($self->[HANDLE_STDOUT]);
717    return;
718  }
719
720  # If any of these change, then the read state is invalidated and
721  # needs to be redefined.
722  my $unique_id     = $self->[UNIQUE_ID];
723  my $driver        = $self->[DRIVER_STDOUT];
724  my $stdout_filter = $self->[FILTER_STDOUT];
725
726  # These can change without redefining the callback since they're
727  # enclosed by reference.
728  my $is_active     = \$self->[IS_ACTIVE];
729  my $close_event   = \$self->[CLOSE_EVENT];
730  my $error_event   = \$self->[ERROR_EVENT];
731
732  # Register the select-read handler for STDOUT.
733  if (
734    $stdout_filter->can("get_one") and
735    $stdout_filter->can("get_one_start")
736  ) {
737    $poe_kernel->state(
738      $self->[STATE_STDOUT] = ref($self) . "($unique_id) -> select stdout",
739      sub {
740        # prevents SEGV
741        0 && CRIMSON_SCOPE_HACK('<');
742
743        # subroutine starts here
744        my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
745        if (defined(my $raw_input = $driver->get($handle))) {
746          $stdout_filter->get_one_start($raw_input);
747          while (1) {
748            my $next_rec = $stdout_filter->get_one();
749            last unless @$next_rec;
750            foreach my $cooked_input (@$next_rec) {
751              $k->call($me, $$stdout_event, $cooked_input, $unique_id);
752            }
753          }
754        }
755        else {
756          $$error_event and $k->call(
757            $me, $$error_event,
758            'read', ($!+0), $!, $unique_id, 'STDOUT'
759          );
760          unless (--$$is_active) {
761            $k->call( $me, $$close_event, $unique_id )
762              if defined $$close_event;
763          }
764          $k->select_read($handle);
765        }
766      }
767    );
768  }
769
770  # Otherwise we can't get one.
771  else {
772    $poe_kernel->state(
773      $self->[STATE_STDOUT] = ref($self) . "($unique_id) -> select stdout",
774      sub {
775        # prevents SEGV
776        0 && CRIMSON_SCOPE_HACK('<');
777
778        # subroutine starts here
779        my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
780        if (defined(my $raw_input = $driver->get($handle))) {
781          foreach my $cooked_input (@{$stdout_filter->get($raw_input)}) {
782            $k->call($me, $$stdout_event, $cooked_input, $unique_id);
783          }
784        }
785        else {
786          $$error_event and
787            $k->call(
788              $me, $$error_event,
789              'read', ($!+0), $!, $unique_id, 'STDOUT'
790            );
791          unless (--$$is_active) {
792            $k->call( $me, $$close_event, $unique_id )
793              if defined $$close_event;
794          }
795          $k->select_read($handle);
796        }
797      }
798    );
799  }
800
801  # register the state's select
802  $poe_kernel->select_read($self->[HANDLE_STDOUT], $self->[STATE_STDOUT]);
803}
804
805#------------------------------------------------------------------------------
806# Define the internal state that will read input from the child
807# process' STDERR pipe.
808
809sub _define_stderr_reader {
810  my $self = shift;
811
812  # Can't do anything if we don't have a handle.
813  return unless defined $self->[HANDLE_STDERR];
814
815  # No event?  Unregister the handler and leave.
816  my $stderr_event  = \$self->[EVENT_STDERR];
817  unless ($$stderr_event) {
818    $poe_kernel->select_read($self->[HANDLE_STDERR]);
819    return;
820  }
821
822  my $unique_id     = $self->[UNIQUE_ID];
823  my $driver        = $self->[DRIVER_STDERR];
824  my $stderr_filter = $self->[FILTER_STDERR];
825
826  # These can change without redefining the callback since they're
827  # enclosed by reference.
828  my $error_event   = \$self->[ERROR_EVENT];
829  my $close_event   = \$self->[CLOSE_EVENT];
830  my $is_active     = \$self->[IS_ACTIVE];
831
832  # Register the select-read handler for STDERR.
833  if (
834    $stderr_filter->can("get_one") and
835    $stderr_filter->can("get_one_start")
836  ) {
837    $poe_kernel->state(
838      $self->[STATE_STDERR] = ref($self) . "($unique_id) -> select stderr",
839      sub {
840        # prevents SEGV
841        0 && CRIMSON_SCOPE_HACK('<');
842
843        # subroutine starts here
844        my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
845        if (defined(my $raw_input = $driver->get($handle))) {
846          $stderr_filter->get_one_start($raw_input);
847          while (1) {
848            my $next_rec = $stderr_filter->get_one();
849            last unless @$next_rec;
850            foreach my $cooked_input (@$next_rec) {
851              $k->call($me, $$stderr_event, $cooked_input, $unique_id);
852            }
853          }
854        }
855        else {
856          $$error_event and $k->call(
857            $me, $$error_event,
858            'read', ($!+0), $!, $unique_id, 'STDERR'
859          );
860          unless (--$$is_active) {
861            $k->call( $me, $$close_event, $unique_id )
862              if defined $$close_event;
863          }
864          $k->select_read($handle);
865        }
866      }
867    );
868  }
869
870  # Otherwise we can't get_one().
871  else {
872    $poe_kernel->state(
873      $self->[STATE_STDERR] = ref($self) . "($unique_id) -> select stderr",
874      sub {
875        # prevents SEGV
876        0 && CRIMSON_SCOPE_HACK('<');
877
878        # subroutine starts here
879        my ($k, $me, $handle) = @_[KERNEL, SESSION, ARG0];
880        if (defined(my $raw_input = $driver->get($handle))) {
881          foreach my $cooked_input (@{$stderr_filter->get($raw_input)}) {
882            $k->call($me, $$stderr_event, $cooked_input, $unique_id);
883          }
884        }
885        else {
886          $$error_event and $k->call(
887            $me, $$error_event,
888            'read', ($!+0), $!, $unique_id, 'STDERR'
889          );
890          unless (--$$is_active) {
891            $k->call( $me, $$close_event, $unique_id )
892              if defined $$close_event;
893          }
894          $k->select_read($handle);
895        }
896      }
897    );
898  }
899
900  # Register the state's select.
901  $poe_kernel->select_read($self->[HANDLE_STDERR], $self->[STATE_STDERR]);
902}
903
904#------------------------------------------------------------------------------
905# Redefine events.
906
907sub event {
908  my $self = shift;
909  push(@_, undef) if (scalar(@_) & 1);
910
911  my ($redefine_stdin, $redefine_stdout, $redefine_stderr) = (0, 0, 0);
912
913  while (@_) {
914    my ($name, $event) = splice(@_, 0, 2);
915
916    if ($name eq 'StdinEvent') {
917      $self->[EVENT_STDIN] = $event;
918      $redefine_stdin = 1;
919    }
920    elsif ($name eq 'StdoutEvent') {
921      $self->[EVENT_STDOUT] = $event;
922      $redefine_stdout = 1;
923    }
924    elsif ($name eq 'StderrEvent') {
925      if ($self->[CONDUIT_TYPE] ne 'pty') {
926        $self->[EVENT_STDERR] = $event;
927        $redefine_stderr = 1;
928      }
929      else {
930        carp "ignoring StderrEvent on a pty conduit";
931      }
932    }
933    elsif ($name eq 'ErrorEvent') {
934      $self->[ERROR_EVENT] = $event;
935    }
936    elsif ($name eq 'CloseEvent') {
937      $self->[CLOSE_EVENT] = $event;
938    }
939    else {
940      carp "ignoring unknown Run parameter '$name'";
941    }
942  }
943
944  # Recalculate the active handles count.
945  my $active_count = 0;
946  $active_count++ if $self->[EVENT_STDOUT] and $self->[HANDLE_STDOUT];
947  $active_count++ if $self->[EVENT_STDERR] and $self->[HANDLE_STDERR];
948  $self->[IS_ACTIVE] = $active_count;
949}
950
951#------------------------------------------------------------------------------
952# Destroy the wheel.
953
954sub DESTROY {
955  my $self = shift;
956
957  return if(ref POE::Kernel->get_active_session eq 'POE::Kernel');
958
959  # Turn off the STDIN thing.
960  if ($self->[HANDLE_STDIN]) {
961    $poe_kernel->select_write($self->[HANDLE_STDIN]);
962    $self->[HANDLE_STDIN] = undef;
963  }
964
965  if ($self->[STATE_STDIN]) {
966    $poe_kernel->state($self->[STATE_STDIN]);
967    $self->[STATE_STDIN] = undef;
968  }
969
970  if ($self->[HANDLE_STDOUT]) {
971    $poe_kernel->select_read($self->[HANDLE_STDOUT]);
972    $self->[HANDLE_STDOUT] = undef;
973  }
974  if ($self->[STATE_STDOUT]) {
975    $poe_kernel->state($self->[STATE_STDOUT]);
976    $self->[STATE_STDOUT] = undef;
977  }
978
979  if ($self->[HANDLE_STDERR]) {
980    $poe_kernel->select_read($self->[HANDLE_STDERR]);
981    $self->[HANDLE_STDERR] = undef;
982  }
983  if ($self->[STATE_STDERR]) {
984    $poe_kernel->state($self->[STATE_STDERR]);
985    $self->[STATE_STDERR] = undef;
986  }
987
988  &POE::Wheel::free_wheel_id($self->[UNIQUE_ID]);
989}
990
991#------------------------------------------------------------------------------
992# Queue input for the child process.
993
994sub put {
995  my ($self, @chunks) = @_;
996
997  # Avoid big bada boom if someone put()s on a dead wheel.
998  croak "Called put() on a wheel without an open STDIN handle" unless (
999    $self->[HANDLE_STDIN]
1000  );
1001
1002  if (
1003    $self->[OCTETS_STDIN] =  # assignment on purpose
1004    $self->[DRIVER_STDIN]->put($self->[FILTER_STDIN]->put(\@chunks))
1005  ) {
1006    $poe_kernel->select_resume_write($self->[HANDLE_STDIN]);
1007  }
1008
1009  # No watermark.
1010  return 0;
1011}
1012
1013#------------------------------------------------------------------------------
1014# Pause and resume various input events.
1015
1016sub pause_stdout {
1017  my $self = shift;
1018  return unless defined $self->[HANDLE_STDOUT];
1019  $poe_kernel->select_pause_read($self->[HANDLE_STDOUT]);
1020}
1021
1022sub pause_stderr {
1023  my $self = shift;
1024  return unless defined $self->[HANDLE_STDERR];
1025  $poe_kernel->select_pause_read($self->[HANDLE_STDERR]);
1026}
1027
1028sub resume_stdout {
1029  my $self = shift;
1030  return unless defined $self->[HANDLE_STDOUT];
1031  $poe_kernel->select_resume_read($self->[HANDLE_STDOUT]);
1032}
1033
1034sub resume_stderr {
1035  my $self = shift;
1036  return unless defined $self->[HANDLE_STDERR];
1037  $poe_kernel->select_resume_read($self->[HANDLE_STDERR]);
1038}
1039
1040# Shutdown the pipe that leads to the child's STDIN.
1041sub shutdown_stdin {
1042  my $self = shift;
1043  return unless defined $self->[HANDLE_STDIN];
1044
1045  $poe_kernel->select_write($self->[HANDLE_STDIN], undef);
1046
1047  eval { local $^W = 0; shutdown($self->[HANDLE_STDIN], 1) };
1048  if ($@ or $self->[HANDLE_STDIN] != $self->[HANDLE_STDOUT]) {
1049    close $self->[HANDLE_STDIN];
1050  }
1051
1052  $self->[HANDLE_STDIN] = undef;
1053}
1054
1055#------------------------------------------------------------------------------
1056# Redefine filters, one at a time or at once.  This is based on PG's
1057# code in Wheel::ReadWrite.
1058
1059sub _transfer_stdout_buffer {
1060  my ($self, $buf) = @_;
1061
1062  my $old_output_filter = $self->[FILTER_STDOUT];
1063
1064  # Assign old buffer contents to the new filter, and send out any
1065  # pending packets.
1066
1067  # Use "get_one" if the new filter implements it.
1068  if (defined $buf) {
1069    if (
1070      $old_output_filter->can("get_one") and
1071      $old_output_filter->can("get_one_start")
1072    ) {
1073      $old_output_filter->get_one_start($buf);
1074
1075      # Don't bother to continue if the filter has switched out from
1076      # under our feet again.  The new switcher will finish the job.
1077
1078      while ($self->[FILTER_STDOUT] == $old_output_filter) {
1079        my $next_rec = $old_output_filter->get_one();
1080        last unless @$next_rec;
1081        foreach my $cooked_input (@$next_rec) {
1082          $poe_kernel->call(
1083            $poe_kernel->get_active_session(), $self->[EVENT_STDOUT],
1084            $cooked_input, $self->[UNIQUE_ID]
1085          );
1086        }
1087      }
1088    }
1089
1090    # Otherwise use the old get() behavior.
1091    else {
1092      foreach my $cooked_input (@{$self->[FILTER_STDOUT]->get($buf)}) {
1093        $poe_kernel->call(
1094          $poe_kernel->get_active_session(), $self->[EVENT_STDOUT],
1095          $cooked_input, $self->[UNIQUE_ID]
1096        );
1097      }
1098    }
1099  }
1100}
1101
1102sub _transfer_stderr_buffer {
1103  my ($self, $buf) = @_;
1104
1105  my $old_output_filter = $self->[FILTER_STDERR];
1106
1107  # Assign old buffer contents to the new filter, and send out any
1108  # pending packets.
1109
1110  # Use "get_one" if the new filter implements it.
1111  if (defined $buf) {
1112    if (
1113      $old_output_filter->can("get_one") and
1114      $old_output_filter->can("get_one_start")
1115    ) {
1116      $old_output_filter->get_one_start($buf);
1117
1118      # Don't bother to continue if the filter has switched out from
1119      # under our feet again.  The new switcher will finish the job.
1120
1121      while ($self->[FILTER_STDERR] == $old_output_filter) {
1122        my $next_rec = $old_output_filter->get_one();
1123        last unless @$next_rec;
1124        foreach my $cooked_input (@$next_rec) {
1125          $poe_kernel->call(
1126            $poe_kernel->get_active_session(), $self->[EVENT_STDERR],
1127            $cooked_input, $self->[UNIQUE_ID]
1128          );
1129        }
1130      }
1131    }
1132
1133    # Otherwise use the old get() behavior.
1134    else {
1135      foreach my $cooked_input (@{$self->[FILTER_STDERR]->get($buf)}) {
1136        $poe_kernel->call(
1137          $poe_kernel->get_active_session(), $self->[EVENT_STDERR],
1138          $cooked_input, $self->[UNIQUE_ID]
1139        );
1140      }
1141    }
1142  }
1143}
1144
1145sub set_stdio_filter {
1146  my ($self, $new_filter) = @_;
1147  $self->set_stdout_filter($new_filter);
1148  $self->set_stdin_filter($new_filter);
1149}
1150
1151sub set_stdin_filter {
1152  my ($self, $new_filter) = @_;
1153  $self->[FILTER_STDIN] = $new_filter;
1154}
1155
1156sub set_stdout_filter {
1157  my ($self, $new_filter) = @_;
1158
1159  my $buf = $self->[FILTER_STDOUT]->get_pending();
1160  $self->[FILTER_STDOUT] = $new_filter;
1161
1162  $self->_transfer_stdout_buffer($buf);
1163}
1164
1165sub set_stderr_filter {
1166  my ($self, $new_filter) = @_;
1167
1168  my $buf = $self->[FILTER_STDERR]->get_pending();
1169  $self->[FILTER_STDERR] = $new_filter;
1170
1171  $self->_transfer_stderr_buffer($buf);
1172}
1173
1174sub get_stdin_filter {
1175  my $self = shift;
1176  return $self->[FILTER_STDIN];
1177}
1178
1179sub get_stdout_filter {
1180  my $self = shift;
1181  return $self->[FILTER_STDOUT];
1182}
1183
1184sub get_stderr_filter {
1185  my $self = shift;
1186  return $self->[FILTER_STDERR];
1187}
1188
1189#------------------------------------------------------------------------------
1190# Data accessors.
1191
1192sub get_driver_out_octets {
1193  $_[0]->[OCTETS_STDIN];
1194}
1195
1196sub get_driver_out_messages {
1197  $_[0]->[DRIVER_STDIN]->get_out_messages_buffered();
1198}
1199
1200sub ID {
1201  $_[0]->[UNIQUE_ID];
1202}
1203
1204sub PID {
1205  $_[0]->[CHILD_PID];
1206}
1207
1208sub kill {
1209  my ($self, $signal) = @_;
1210  $signal = 'TERM' unless defined $signal;
1211  if ( $self->[MSWIN32_GROUP_PID] ) {
1212    # TODO use https://rt.cpan.org/Ticket/Display.html?id=67774 when available :)
1213    Win32::Process::KillProcess( $self->[MSWIN32_GROUP_PID], 293 ) ? 1 : 0;
1214  }
1215  else {
1216    eval { kill $signal, $self->[CHILD_PID] };
1217  }
1218}
1219
1220### Internal helpers.
1221
1222sub _redirect_child_stdio_in_hell {
1223  my ($class, $stdin_read, $stdout_write, $stderr_write) = @_;
1224
1225  # Win32 needs the stdio handles closed before they're reopened
1226  # because the standard handles aren't dup()'d.
1227
1228  close STDIN;
1229  close STDOUT;
1230  close STDERR;
1231
1232  $class->_redirect_child_stdio_sanely(
1233    $stdin_read, $stdout_write, $stderr_write
1234  );
1235
1236  # The Win32 pseudo fork sets up the std handles in the child
1237  # based on the true win32 handles.  The reopening of stdio
1238  # handles isn't enough.  We must also set the underlying
1239  # Win32 notion of these handles for completeness.
1240  #
1241  # Only necessary for the exec, as Perl CODE subroutine goes
1242  # through 0/1/2 which are correct.  But of course that coderef
1243  # might invoke exec, so better do it regardless.
1244  #
1245  # HACK: Using Win32::Console as nothing else exposes
1246  # SetStdHandle
1247  #
1248  # TODO - https://rt.cpan.org/Ticket/Display.html?id=50068 claims
1249  # that these _SetStdHandle() calls may leak memory.  Do we have
1250  # alternatives?
1251
1252  Win32::Console::_SetStdHandle(
1253    $STD_INPUT_HANDLE,
1254    FdGetOsFHandle(fileno($stdin_read))
1255  ) if defined $stdin_read;
1256
1257  Win32::Console::_SetStdHandle(
1258    $STD_OUTPUT_HANDLE,
1259    FdGetOsFHandle(fileno($stdout_write))
1260  ) if defined $stdout_write;
1261
1262  Win32::Console::_SetStdHandle(
1263    $STD_ERROR_HANDLE,
1264    FdGetOsFHandle(fileno($stderr_write))
1265  ) if defined $stderr_write;
1266}
1267
1268sub _filespec_to_fh {
1269  my ($dest,$mode,$fspec) = @_;
1270  return unless defined $fspec;
1271  if(ref $fspec) {
1272    if (ref $fspec eq 'GLOB') {
1273      open $$dest, "$mode&", $fspec;
1274    } else {
1275      die("Bad file specifier '$fspec'");
1276    }
1277  } else {
1278    open $$dest, $mode, $fspec;
1279  }
1280}
1281
1282sub _redirect_child_stdio_sanely {
1283  my ($class, $stdin_read, $stdout_write, $stderr_write) = @_;
1284
1285  # Note: we use 2-arg open() below because Perl 5.6 doesn't recognize
1286  # the '>&' and '<&' modes with a 3-arg open()
1287
1288  # Redirect STDIN from the read end of the stdin pipe.
1289  if(defined $stdin_read) {
1290    open( STDIN, "<&" . fileno($stdin_read) )
1291      or $class->_warn_and_exit_child(
1292        "can't redirect STDIN in child pid $$: $!", int( $! ) );
1293  }
1294
1295  # Redirect STDOUT to the write end of the stdout pipe.
1296  if(defined $stdout_write) {
1297    open( STDOUT, ">&" . fileno($stdout_write) )
1298      or $class->_warn_and_exit_child(
1299        "can't redirect stdout in child pid $$: $!", int( $! ) );
1300  }
1301    # Redirect STDERR to the write end of the stderr pipe.
1302  if(defined $stderr_write) {
1303    open( STDERR, ">&" . fileno($stderr_write) )
1304      or $class->_warn_and_exit_child(
1305        "can't redirect stderr in child pid $$: $!", int( $! ) );
1306  }
1307}
1308
1309sub _exit_child_any_way_we_can {
1310  my $class = shift;
1311  my $exitval = shift || 0;
1312
1313  # First make sure stdio are flushed.
1314  close STDIN  if defined fileno(STDIN); # Voodoo?
1315  close STDOUT if defined fileno(STDOUT);
1316  close STDERR if defined fileno(STDERR);
1317
1318  # On Windows, subprocesses run in separate threads.  All the "fancy"
1319  # methods act on entire processes, so they also exit the parent.
1320
1321  unless (POE::Kernel::RUNNING_IN_HELL) {
1322    # Try to avoid triggering END blocks and object destructors.
1323    eval { POSIX::_exit( $exitval ); };
1324
1325    # TODO those methods will not exit with $exitval... what to do?
1326    eval { CORE::kill KILL => $$; };
1327    eval { exec("$^X -e 0"); };
1328  } else {
1329    eval { CORE::kill( KILL => $$ ); };
1330
1331    # TODO Interestingly enough, the KILL is not enough to terminate this process...
1332    # However, it *is* enough to stop execution of END blocks/etc
1333    # So we will end up falling through to the exit( $exitval ) below
1334  }
1335
1336  # Do what we must.
1337  exit( $exitval );
1338}
1339
1340# RUNNING_IN_HELL use Win32::Process to create a pucker new shiny
1341# process. It'll inherit our processes handles which is neat.
1342
1343sub _exec_in_hell {
1344  my (
1345    $class, $close_on_call, $sem_pipe_write,
1346    $program, $prog_args
1347  ) = @_;
1348
1349  # Close any close-on-exec file descriptors.
1350  # Except STDIN, STDOUT, and STDERR, of course.
1351
1352  if ($close_on_call) {
1353    for (0..MAX_OPEN_FDS-1) {
1354      next if fileno(STDIN) == $_;
1355      next if fileno(STDOUT) == $_;
1356      next if fileno(STDERR) == $_;
1357      POSIX::close($_);
1358    }
1359  }
1360
1361  my ($appname, $cmdline);
1362
1363  if (ref $program eq 'ARRAY') {
1364    $appname = $program->[0];
1365    $cmdline = join(
1366      ' ',
1367      map { /\s/ && ! /"/ ? qq{"$_"} : $_ }
1368      (@$program, @$prog_args)
1369    );
1370  }
1371  else {
1372    $appname = undef;
1373    $cmdline = join(
1374      ' ', $program,
1375      map { /\s/ && ! /"/ ? qq{"$_"} : $_ }
1376      @$prog_args
1377    );
1378  }
1379
1380  my $w32job;
1381
1382  unless ( $w32job = Win32::Job->new() ) {
1383    print $sem_pipe_write "go\n\n"; # TODO why the double newline?
1384    close $sem_pipe_write;
1385    $class->_warn_and_exit_child(
1386      Win32::FormatMessage( Win32::GetLastError() ), Win32::GetLastError() );
1387  }
1388
1389  my $w32pid;
1390
1391  unless ( $w32pid = $w32job->spawn( $appname, $cmdline ) ) {
1392    print $sem_pipe_write "go\n";
1393    close $sem_pipe_write;
1394    $class->_warn_and_exit_child(
1395      Win32::FormatMessage( Win32::GetLastError() ), Win32::GetLastError() );
1396  }
1397
1398  print $sem_pipe_write "$w32pid\n";
1399  close $sem_pipe_write;
1400
1401  # TODO why 60? Why not MAX_INT so we don't do unnecessary work?
1402  my $ok = $w32job->watch( sub { 0 }, 60 );
1403  my $hashref = $w32job->status();
1404
1405  # In case flushing them wasn't good enough.
1406  close STDOUT if defined fileno(STDOUT);
1407  close STDERR if defined fileno(STDERR);
1408
1409  $class->_exit_child_any_way_we_can( $hashref->{$w32pid}->{exitcode} );
1410}
1411
1412# Simple helper to ease the pain of warn+exit
1413sub _warn_and_exit_child {
1414  my( $class, $warning, $exitval ) = @_;
1415
1416  warn "$warning\n";
1417
1418  $class->_exit_child_any_way_we_can( $exitval );
1419}
1420
14211;
1422
1423__END__
1424
1425=head1 NAME
1426
1427POE::Wheel::Run - portably run blocking code and programs in subprocesses
1428
1429=head1 SYNOPSIS
1430
1431  #!/usr/bin/perl
1432
1433  use warnings;
1434  use strict;
1435
1436  use POE qw( Wheel::Run );
1437
1438  POE::Session->create(
1439    inline_states => {
1440      _start           => \&on_start,
1441      got_child_stdout => \&on_child_stdout,
1442      got_child_stderr => \&on_child_stderr,
1443      got_child_close  => \&on_child_close,
1444      got_child_signal => \&on_child_signal,
1445    }
1446  );
1447
1448  POE::Kernel->run();
1449  exit 0;
1450
1451  sub on_start {
1452    my $child = POE::Wheel::Run->new(
1453      Program => [ "/bin/ls", "-1", "/" ],
1454      StdoutEvent  => "got_child_stdout",
1455      StderrEvent  => "got_child_stderr",
1456      CloseEvent   => "got_child_close",
1457    );
1458
1459    $_[KERNEL]->sig_child($child->PID, "got_child_signal");
1460
1461    # Wheel events include the wheel's ID.
1462    $_[HEAP]{children_by_wid}{$child->ID} = $child;
1463
1464    # Signal events include the process ID.
1465    $_[HEAP]{children_by_pid}{$child->PID} = $child;
1466
1467    print(
1468      "Child pid ", $child->PID,
1469      " started as wheel ", $child->ID, ".\n"
1470    );
1471  }
1472
1473  # Wheel event, including the wheel's ID.
1474  sub on_child_stdout {
1475    my ($stdout_line, $wheel_id) = @_[ARG0, ARG1];
1476    my $child = $_[HEAP]{children_by_wid}{$wheel_id};
1477    print "pid ", $child->PID, " STDOUT: $stdout_line\n";
1478  }
1479
1480  # Wheel event, including the wheel's ID.
1481  sub on_child_stderr {
1482    my ($stderr_line, $wheel_id) = @_[ARG0, ARG1];
1483    my $child = $_[HEAP]{children_by_wid}{$wheel_id};
1484    print "pid ", $child->PID, " STDERR: $stderr_line\n";
1485  }
1486
1487  # Wheel event, including the wheel's ID.
1488  sub on_child_close {
1489    my $wheel_id = $_[ARG0];
1490    my $child = delete $_[HEAP]{children_by_wid}{$wheel_id};
1491
1492    # May have been reaped by on_child_signal().
1493    unless (defined $child) {
1494      print "wid $wheel_id closed all pipes.\n";
1495      return;
1496    }
1497
1498    print "pid ", $child->PID, " closed all pipes.\n";
1499    delete $_[HEAP]{children_by_pid}{$child->PID};
1500  }
1501
1502  sub on_child_signal {
1503    print "pid $_[ARG1] exited with status $_[ARG2].\n";
1504    my $child = delete $_[HEAP]{children_by_pid}{$_[ARG1]};
1505
1506    # May have been reaped by on_child_close().
1507    return unless defined $child;
1508
1509    delete $_[HEAP]{children_by_wid}{$child->ID};
1510  }
1511
1512=head1 DESCRIPTION
1513
1514POE::Wheel::Run executes a program or block of code in a subprocess,
1515created the usual way: using fork().  The parent process may exchange
1516information with the child over the child's STDIN, STDOUT and STDERR
1517filehandles.
1518
1519In the parent process, the POE::Wheel::Run object represents the child
1520process.  It has methods such as PID() and kill() to query and manage
1521the child process.
1522
1523POE::Wheel::Run's put() method sends data to the child's STDIN.  Child
1524output on STDOUT and STDERR may be dispatched as events within the
1525parent, if requested.
1526
1527POE::Wheel::Run can also notify the parent when the child has closed
1528its output filehandles.  Some programs remain active, but they close
1529their output filehandles to indicate they are done writing.
1530
1531A more reliable way to detect child exit is to use POE::Kernel's
1532sig_child() method to wait for the wheel's process to be reaped.  It
1533is in fact vital to use sig_child() in all circumstances since without
1534it, POE will not try to reap child processes.
1535
1536Failing to use sig_child() has in the past led to wedged machines.
1537Long-running programs have leaked processes, eventually consuming all
1538available slots in the process table and requiring reboots.
1539
1540Because process leaks are so severe, POE::Kernel will check for this
1541condition on exit and display a notice if it finds that processes are
1542leaking.  Developers should heed these warnings.
1543
1544POE::Wheel::Run communicates with the child process in a line-based
1545fashion by default.  Programs may override this by specifying some
1546other POE::Filter object in L</StdinFilter>, L</StdoutFilter>,
1547L</StdioFilter> and/or L</StderrFilter>.
1548
1549=head1 PUBLIC METHODS
1550
1551=head2 Constructor
1552
1553POE::Wheel subclasses tend to perform a lot of setup so that they run
1554lighter and faster.  POE::Wheel::Run's constructor is no exception.
1555
1556=head3 new
1557
1558new() creates and returns a new POE::Wheel::Run object.  If it's
1559successful, the object will represent a child process with certain
1560specified qualities.  It also provides an OO- and event-based
1561interface for asynchronously interacting with the process.
1562
1563=head4 Conduit
1564
1565Conduit specifies the inter-process communications mechanism that will
1566be used to pass data between the parent and child process.  Conduit
1567may be one of "pipe", "socketpair", "inet", "pty", or "pty-pipe".
1568POE::Wheel::Run will use the most appropriate Conduit for the run-time
1569(not the compile-time) operating system, but this varies from one OS
1570to the next.
1571
1572Internally, POE::Wheel::Run passes the Conduit type to
1573L<POE::Pipe::OneWay> and L<POE::Pipe::TwoWay>.  These helper classes
1574were created to make IPC portable and reusable.  They do not require
1575the rest of POE.
1576
1577Three Conduit types use pipes or pipelike inter-process communication:
1578"pipe", "socketpair" and "inet".  They determine whether the internal
1579IPC uses pipe(), socketpair() or Internet sockets.  These Conduit
1580values are passed through to L<POE::Pipe::OneWay> or
1581L<POE::Pipe::TwoWay> internally.
1582
1583The "pty" conduit type runs the child process under a pseudo-tty,
1584which is created by L<IO::Pty>.  Pseudo-ttys (ptys) convince child
1585processes that they are interacting with terminals rather than pipes.
1586This may be used to trick programs like ssh into believing it's secure
1587to prompt for a password, although passphraseless identities might be
1588better for that.
1589
1590The "pty" conduit cannot separate STDERR from STDOUT, but the
1591"pty-pipe" mode can.
1592
1593The "pty-pipe" conduit uses a pty for STDIN and STDOUT and a one-way
1594pipe for STDERR.  The additional pipe keeps STDERR output separate
1595from STDOUT.
1596
1597The L<IO::Pty> module is only loaded if "pty" or "pty-pipe" is used.
1598It's not a dependency until it's actually needed.
1599
1600=for comment
1601TODO - Example.
1602
1603=head4 Winsize
1604
1605Winsize sets the child process' terminal size.  Its value should be an
1606arrayref with four elements.  The first two elements must be the
1607number of lines and columns for the child's terminal window,
1608respectively.  The second pair of elements describe the terminal's X
1609and Y dimensions in pixels.  If the last pair is missing, they will be calculated
1610from the lines and columns using a 9x16 cell size.
1611
1612  $_[HEAP]{child} = POE::Wheel::Run->new(
1613    # ... among other things ...
1614    Winsize => [ 25, 80, 720, 400 ],
1615  );
1616
1617Winsize is only valid for conduits that use pseudo-ttys: "pty" and
1618"pty-pipe".  Other conduits don't simulate terminals, so they don't
1619have window sizes.
1620
1621Winsize defaults to the parent process' window size, assuming the
1622parent process has a terminal to query.
1623
1624=head4 CloseOnCall
1625
1626CloseOnCall, when true, turns on close-on-exec emulation for
1627subprocesses that don't actually call exec().  These would be
1628instances when the child is running a block of code rather than
1629executing an external program.  For example:
1630
1631  $_[HEAP]{child} = POE::Wheel::Run->new(
1632    # ... among other things ...
1633    CloseOnCall => 1,
1634    Program => \&some_function,
1635  );
1636
1637CloseOnCall is off (0) by default.
1638
1639CloseOnCall works by closing all file descriptors greater than $^F in
1640the child process before calling the application's code.  For more
1641details, please the discussion of $^F in L<perlvar>.
1642
1643=head4 StdioDriver
1644
1645StdioDriver specifies a single L<POE::Driver> object to be used for
1646both STDIN and STDOUT.  It's equivalent to setting L</StdinDriver> and
1647L</StdoutDriver> to the same L<POE::Driver> object.
1648
1649POE::Wheel::Run will create and use a L<POE::Driver::SysRW> driver of
1650one isn't specified.  This is by far the most common use case, so it's
1651the default.
1652
1653=head4 StdinDriver
1654
1655C<StdinDriver> sets the L<POE::Driver> used to write to the child
1656process' STDIN IPC conduit.  It is almost never needed.  Omitting it
1657will allow POE::Wheel::Run to use an internally created
1658L<POE::Driver::SysRW> object.
1659
1660=head4 StdoutDriver
1661
1662C<StdoutDriver> sets the L<POE::Driver> object that will be used to
1663read from the child process' STDOUT conduit.  It's almost never
1664needed.  If omitted, POE::Wheel::Run will internally create and use
1665a L<POE::Driver::SysRW> object.
1666
1667=head4 StderrDriver
1668
1669C<StderrDriver> sets the driver that will be used to read from the
1670child process' STDERR conduit.  As with L</StdoutDriver>, it's almost
1671always preferable to let POE::Wheel::Run instantiate its own driver.
1672
1673=head4 CloseEvent
1674
1675CloseEvent contains the name of an event that the wheel will emit when
1676the child process closes its last open output handle.  This is a
1677consistent notification that the child is done sending output.  Please
1678note that it does not signal when the child process has exited.
1679Programs should use sig_child() to detect that.
1680
1681While it is impossible for ErrorEvent or StdoutEvent to happen after
1682CloseEvent, there is no such guarantee for CHLD, which may happen before
1683or after CloseEvent.
1684
1685In addition to the usual POE parameters, each CloseEvent comes with
1686one of its own:
1687
1688C<ARG0> contains the wheel's unique ID.  This can be used to keep
1689several child processes separate when they're managed by the same
1690session.
1691
1692A sample close event handler:
1693
1694  sub close_state {
1695    my ($heap, $wheel_id) = @_[HEAP, ARG0];
1696
1697    my $child = delete $heap->{child}->{$wheel_id};
1698    print "Child ", $child->PID, " has finished.\n";
1699  }
1700
1701=head4 ErrorEvent
1702
1703ErrorEvent contains the name of an event to emit if something fails.
1704It is optional; if omitted, the wheel will not notify its session if
1705any errors occur.  However, POE::Wheel::Run->new() will still throw an
1706exception if it fails.
1707
1708C<ARG0> contains the name of the operation that failed.  It may be
1709'read', 'write', 'fork', 'exec' or the name of some other function or
1710task.  The actual values aren't yet defined.  They will probably not
1711correspond so neatly to Perl builtin function names.
1712
1713C<ARG1> and C<ARG2> hold numeric and string values for C<$!>,
1714respectively.  C<"$!"> will eq C<""> for read error 0 (child process
1715closed the file handle).
1716
1717C<ARG3> contains the wheel's unique ID.
1718
1719C<ARG4> contains the name of the child filehandle that has the error.
1720It may be "STDIN", "STDOUT", or "STDERR".  The sense of C<ARG0> will
1721be the opposite of what you might normally expect for these handles.
1722For example, POE::Wheel::Run will report a "read" error on "STDOUT"
1723because it tried to read data from the child's STDOUT handle.
1724
1725A sample error event handler:
1726
1727  sub error_state {
1728    my ($operation, $errnum, $errstr, $wheel_id) = @_[ARG0..ARG3];
1729    $errstr = "remote end closed" if $operation eq "read" and !$errnum;
1730    warn "Wheel $wheel_id generated $operation error $errnum: $errstr\n";
1731  }
1732
1733Note that unless you deactivate the signal pipe, you might also see C<EIO>
1734(5) error during read operations.
1735
1736=head4 StdinEvent
1737
1738StdinEvent contains the name of an event that Wheel::Run emits
1739whenever everything queued by its put() method has been flushed to the
1740child's STDIN handle.  It is the equivalent to POE::Wheel::ReadWrite's
1741FlushedEvent.
1742
1743StdinEvent comes with only one additional parameter: C<ARG0> contains
1744the unique ID for the wheel that sent the event.
1745
1746=head4 StdoutEvent
1747
1748StdoutEvent contains the name of an event  that Wheel::Run emits
1749whenever the child process writes something to its STDOUT filehandle.
1750In other words, whatever the child prints to STDOUT, the parent
1751receives a StdoutEvent---provided that the child prints something
1752compatible with the parent's StdoutFilter.
1753
1754StdoutEvent comes with two parameters.  C<ARG0> contains the
1755information that the child wrote to STDOUT.  C<ARG1> holds the unique
1756ID of the wheel that read the output.
1757
1758  sub stdout_state {
1759    my ($heap, $input, $wheel_id) = @_[HEAP, ARG0, ARG1];
1760    print "Child process in wheel $wheel_id wrote to STDOUT: $input\n";
1761  }
1762
1763=head4 StderrEvent
1764
1765StderrEvent behaves exactly as StdoutEvent, except for data the child
1766process writes to its STDERR filehandle.
1767
1768StderrEvent comes with two parameters.  C<ARG0> contains the
1769information that the child wrote to STDERR.  C<ARG1> holds the unique
1770ID of the wheel that read the output.
1771
1772  sub stderr_state {
1773    my ($heap, $input, $wheel_id) = @_[HEAP, ARG0, ARG1];
1774    print "Child process in wheel $wheel_id wrote to STDERR: $input\n";
1775  }
1776
1777=head4 RedirectStdout
1778
1779This is a filehandle or filename to which standard output will be redirected.
1780It is an error to use this option together with StdoutEvent. This is useful
1781in case your program needs to have standard I/O, but do not actually care for
1782its contents to be visible to the parent.
1783
1784=head4 RedirectStderr
1785
1786Just like RedirectStdout, but with standard error. It is an error to use this
1787together with StderrEvent
1788
1789=head4 RedirectStdin
1790
1791This is a filehandle or filename which the child process will use as its
1792standard input. It is an error to use this option with StdinEvent
1793
1794=head4 RedirectOutput
1795
1796This will redirect stderr and stdout to the same filehandle. This is equivalent
1797to do doing something like
1798
1799  $ something > /path/to/output 2>&1
1800
1801in bourne shell.
1802
1803=head4 NoStdin
1804
1805While output filehandles will be closed if there are no events to be received on
1806them, stdin is open by default - because lack of an event handler does not
1807necessarily mean there is no desired input stream. This option explicitly
1808disables the creation of an IPC stdin conduit.
1809
1810=head4 StdioFilter
1811
1812StdioFilter, if used, must contain an instance of a POE::Filter
1813subclass.  This filter describes how the parent will format put() data
1814for the child's STDIN, and how the parent will parse the child's
1815STDOUT.
1816
1817If STDERR will also be parsed, then a separate StderrFilter will also
1818be needed.
1819
1820StdioFilter defaults to a POE::Filter::Line instance, but only if both
1821StdinFilter and StdoutFilter are not specified.  If either StdinFilter
1822or StdoutFilter is used, then StdioFilter is illegal.
1823
1824=head4 StdinFilter
1825
1826StdinFilter may be used to specify a particular STDIN serializer that
1827is different from the STDOUT parser.  If specified, it conflicts with
1828StdioFilter.  StdinFilter's value, if specified, must be an instance
1829of a POE::Filter subclass.
1830
1831Without a StdinEvent, StdinFilter is illegal.
1832
1833=head4 StdoutFilter
1834
1835StdoutFilter may be used to specify a particular STDOUT parser that is
1836different from the STDIN serializer.  If specified, it conflicts with
1837StdioFilter.  StdoutFilter's value, if specified, must be an instance
1838of a POE::Filter subclass.
1839
1840Without a StdoutEvent, StdoutFilter is illegal.
1841
1842=head4 StderrFilter
1843
1844StderrFilter may be used to specify a filter for a child process'
1845STDERR output.  If omitted, POE::Wheel::Run will create and use its
1846own POE::Filter::Line instance, but only if a StderrEvent is
1847specified.
1848
1849Without a StderrEvent, StderrFilter is illegal.
1850
1851=head4 Group
1852
1853Group contains a numeric group ID that the child process should run
1854within.  By default, the child process will run in the same group as
1855the parent.
1856
1857Group is not fully portable.  It may not work on systems that have no
1858concept of user groups.  Also, the parent process may need to run with
1859elevated privileges for the child to be able to change groups.
1860
1861=head4 User
1862
1863User contains a numeric user ID that should own the child process.  By
1864default, the child process will run as the same user as the parent.
1865
1866User is not fully portable.  It may not work on systems that have no
1867concept of users.  Also, the parent process may need to run with
1868elevated privileges for the child to be able to change users.
1869
1870=head4 NoSetSid
1871
1872When true, NoSetSid disables setsid() in the child process.  By
1873default, the child process calls setsid() is called so that it may
1874execute in a separate UNIX session.
1875
1876=head4 NoSetPgrp
1877
1878When true, NoSetPgrp disables setprgp() in the child process. By
1879default, the child process calls setpgrp() to change its process
1880group, if the OS supports that.
1881
1882setsid() is used instead of setpgrp() if Conduit is pty or pty-pipe.
1883See L</NoSetSid>.
1884
1885=head4 Priority
1886
1887Priority adjusts the child process' niceness or priority level,
1888depending on which (if any) the underlying OS supports.  Priority
1889contains a numeric offset which will be added to the parent's priority
1890to determine the child's.
1891
1892The priority offset may be negative, which in UNIX represents a higher
1893priority.  However UNIX requires elevated privileges to increase a
1894process' priority.
1895
1896=head4 Program
1897
1898Program specifies the program to exec() or the block of code to run in
1899the child process.  Program's type is significant.
1900
1901If Program holds a scalar, its value will be executed as
1902exec($program).  Shell metacharacters are significant, per
1903exec(SCALAR) semantics.
1904
1905If Program holds an array reference, it will executed as
1906exec(@$program).  As per exec(ARRAY), shell metacharacters will not be
1907significant.
1908
1909If Program holds a code reference, that code will be called in the
1910child process.  This mode allows POE::Wheel::Run to execute
1911long-running internal code asynchronously, while the usual modes
1912execute external programs.  The child process will exit after that
1913code is finished, in such a way as to avoid DESTROY and END block
1914execution.  See L</Coderef Execution Side Effects> for more details.
1915
1916L<perlfunc> has more information about exec() and the different ways
1917to call it.
1918
1919Please avoid calling exit() explicitly when executing a subroutine.
1920The child process inherits all objects from the parent, including ones
1921that may perform side effects.  POE::Wheel::Run takes special care to
1922avoid object destructors and END blocks in the child process, but
1923calling exit() will trigger them.
1924
1925=head4 ProgramArgs
1926
1927If specified, ProgramArgs should refer to a list of parameters for the
1928program being run.
1929
1930  my @parameters = qw(foo bar baz);  # will be passed to Program
1931  ProgramArgs => \@parameters;
1932
1933=head2 event EVENT_TYPE => EVENT_NAME, ...
1934
1935event() allows programs to change the events that Wheel::Run emits
1936when certain activities occurs.  EVENT_TYPE may be one of the event
1937parameters described in POE::Wheel::Run's constructor.
1938
1939This example changes the events that $wheel emits for STDIN flushing
1940and STDOUT activity:
1941
1942  $wheel->event(
1943    StdinEvent  => 'new-stdin-event',
1944    StdoutEvent => 'new-stdout-event',
1945  );
1946
1947Undefined EVENT_NAMEs disable events.
1948
1949=head2 put RECORDS
1950
1951put() queues up a list of RECORDS that will be sent to the child
1952process' STDIN filehandle.  These records will first be serialized
1953according to the wheel's StdinFilter.  The serialized RECORDS will be
1954flushed asynchronously once the current event handler returns.
1955
1956=head2 get_stdin_filter
1957
1958get_stind_filter() returns the POE::Filter object currently being used
1959to serialize put() records for the child's STDIN filehandle.  The
1960return object may be used according to its own interface.
1961
1962=head2 get_stdout_filter
1963
1964get_stdout_filter() returns the POE::Filter object currently being
1965used to parse what the child process writes to STDOUT.
1966
1967=head2 get_stderr_filter
1968
1969get_stderr_filter() returns the POE::Filter object currently being
1970used to parse what the child process writes to STDERR.
1971
1972=head2 set_stdio_filter FILTER_OBJECT
1973
1974Set StdinFilter and StdoutFilter to the same new FILTER_OBJECT.
1975Unparsed STDOUT data will be parsed later by the new FILTER_OBJECT.
1976However, data already put() will remain serialized by the old filter.
1977
1978=head2 set_stdin_filter FILTER_OBJECT
1979
1980Set StdinFilter to a new FILTER_OBJECT.  Data already put() will
1981remain serialized by the old filter.
1982
1983=head2 set_stdout_filter FILTER_OBJECT
1984
1985Set StdoutFilter to a new FILTER_OBJECT.  Unparsed STDOUT data will be
1986parsed later by the new FILTER_OBJECT.
1987
1988=head2 set_stderr_filter FILTER_OBJECT
1989
1990Set StderrFilter to a new FILTER_OBJECT.  Unparsed STDERR data will be
1991parsed later by the new FILTER_OBJECT.
1992
1993=head2 pause_stdout
1994
1995Pause reading of STDOUT from the child.  The child process may block
1996if the STDOUT IPC conduit fills up.  Reading may be resumed with
1997resume_stdout().
1998
1999=head2 pause_stderr
2000
2001Pause reading of STDERR from the child.  The child process may block
2002if the STDERR IPC conduit fills up.  Reading may be resumed with
2003resume_stderr().
2004
2005=head2 resume_stdout
2006
2007Resume reading from the child's STDOUT filehandle.  This is only
2008meaningful if pause_stdout() has been called and remains in effect.
2009
2010=head2 resume_stderr
2011
2012Resume reading from the child's STDERR filehandle.  This is only
2013meaningful if pause_stderr() has been called and remains in effect.
2014
2015=head2 shutdown_stdin
2016
2017shutdown_stdin() closes the child process' STDIN and stops the wheel
2018from reporting StdinEvent.  It is extremely useful for running
2019utilities that expect to receive EOF on STDIN before they respond.
2020
2021=head2 ID
2022
2023ID() returns the wheel's unique ID.  Every event generated by a
2024POE::Wheel::Run object includes a wheel ID so that it can be matched
2025to the wheel that emitted it.  This lets a single session manage
2026several wheels without becoming confused about which one generated
2027what event.
2028
2029ID() is not the same as PID().
2030
2031=head2 PID
2032
2033PID() returns the process ID for the child represented by the
2034POE::Wheel::Run object.  It's often used as a parameter to
2035sig_child().
2036
2037PID() is not the same as ID().
2038
2039=head2 kill SIGNAL
2040
2041POE::Wheel::Run's kill() method sends a SIGNAL to the child process
2042the object represents.  kill() is often used to force a reluctant
2043program to terminate.  SIGNAL is one of the operating signal names
2044present in %SIG.
2045
2046kill() returns the number of processes successfully signaled: 1 on
2047success, or 0 on failure, since the POE::Wheel::Run object only
2048affects at most a single process.
2049
2050kill() sends SIGTERM if SIGNAL is undef or omitted.
2051
2052=head2 get_driver_out_messages
2053
2054get_driver_out_messages() returns the number of put() records
2055remaining in whole or in part in POE::Wheel::Run's POE::Driver output
2056queue.  It is often used to tell whether the wheel has more input for
2057the child process.
2058
2059In most cases, StdinEvent may be used to trigger activity when all
2060data has been sent to the child process.
2061
2062=head2 get_driver_out_octets
2063
2064get_driver_out_octets() returns the number of serialized octets
2065remaining in POE::Wheel::Run's POE::Driver output queue.  It is often
2066used to tell whether the wheel has more input for the child process.
2067
2068=head1 TIPS AND TRICKS
2069
2070=head2 MSWin32 Support
2071
2072In the past POE::Wheel::Run did not support MSWin32 and users had to
2073use custom work-arounds. Then Chris Williams ( BINGOS ) arrived and
2074saved the day with his L<POE::Wheel::Run::Win32> module. After some
2075testing, it was decided to merge the win32 code into POE::Wheel::Run.
2076Everyone was happy!
2077
2078However, after some investigation Apocalypse ( APOCAL ) found out that
2079in some situations it still didn't behave properly. The root cause was
2080that the win32 code path in POE::Wheel::Run didn't exit cleanly. This
2081means DESTROY and END blocks got executed! After talking with more
2082people, the solution was not pretty.
2083
2084The problem is that there is no equivalent of POSIX::_exit() for MSWin32.
2085Hopefully, in a future version of Perl this can be fixed! In the meantime,
2086POE::Wheel::Run will use CORE::kill() to terminate the child. However,
2087this comes with a caveat: you will leak around 1KB per exec. The code
2088has been improved so the chance of this happening has been reduced.
2089
2090As of now the most reliable way to trigger this is to exec an invalid
2091binary. The definition of "invalid binary" depends on different things,
2092but what it means is that Win32::Job->spawn() failed to run. This will
2093force POE::Wheel::Run to use the workaround to exit the child. If this
2094happens, a very big warning will be printed to the STDERR of the child
2095and the parent process will receive it.
2096
2097If you are a Perl MSWin32 hacker, PLEASE help us with this situation! Go
2098read rt.cpan.org bug #56417 and talk with us/p5p to see where you can
2099contribute.
2100
2101Thanks again for your patience as we continue to improve POE::Wheel::Run
2102on MSWin32!
2103
2104=head3 kill() and ClosedEvent on Windows
2105
2106Windows will often fail to report EOF on pipes when subprocesses are
2107killed.  The work-around is to catch the signal in the subprocess, and
2108exit normally:
2109
2110  my $child = POE::Wheel::Run->new(
2111    Program => sub {
2112      $SIG{INT} = sub { exit };
2113      ...;
2114    },
2115    ...,
2116  );
2117
2118Be sure to kill() the subprocess using the same signal that it catches
2119and exits upon.  Remember, not all signals can be caught by user code.
2120
2121  $child->kill("INT");
2122
2123=head2 Execution Environment
2124
2125It's common to scrub a child process' environment, so that only
2126required, secure values exist.  This amounts to clearing the contents
2127of %ENV and repopulating it.
2128
2129Environment scrubbing is easy when the child process is running a
2130subroutine, but it's not so easy---or at least not as intuitive---when
2131executing external programs.
2132
2133The way we do it is to run a small subroutine in the child process
2134that performs the exec() call for us.
2135
2136  Program => \&exec_with_scrubbed_env,
2137
2138  sub exec_with_scrubbed_env {
2139    delete @ENV{keys @ENV};
2140    $ENV{PATH} = "/bin";
2141    exec(@program_and_args);
2142  }
2143
2144That deletes everything from the environment and sets a simple, secure
2145PATH before executing a program.
2146
2147=head2 Coderef Execution Side Effects
2148
2149The child process is created by fork(), which duplicates the parent
2150process including a copy of POE::Kernel, all running Session
2151instances, events in the queue, watchers, open filehandles, and so on.
2152
2153When executing an external program, the UNIX exec() call immediately
2154replaces the copy of the parent with a completely new program.
2155
2156When executing internal coderefs, however, we must preserve the code
2157and any memory it might reference.  This leads to some potential side
2158effects.
2159
2160=head3 DESTROY and END Blocks Run Twice
2161
2162Objects that were created in the parent process are copied into the
2163child.  When the child exits normally, any DESTROY and END blocks are
2164executed there.  Later, when the parent exits, they may run again.
2165
2166POE::Wheel::Run takes steps to avoid running DESTROY and END blocks in
2167the child process.  It uses POSIX::_exit() to bypass them.  If that
2168fails, it may even kill() itself.
2169
2170If an application needs to exit explicitly, for example to return an
2171error code to the parent process, then please use POSIX::_exit()
2172rather than Perl's core exit().
2173
2174=head3 POE::Kernel's run() method was never called
2175
2176This warning is displayed from POE::Kernel's DESTROY method.  It's a
2177side effect of calling exit() in a child process that was started
2178before C<< POE::Kernel->run() >> could be called.  The child process
2179receives a copy of POE::Kernel where run() wasn't called, even if it
2180was called later in the parent process.
2181
2182The most direct solution is to call POSIX::_exit() rather than exit().
2183This will bypass POE::Kernel's DESTROY, and the message it emits.
2184
2185=head3 Running POE::Kernel in the Child
2186
2187Calling C<< POE::Kernel->run() >> in the child process effectively
2188resumes the copy of the parent process.  This is rarely (if ever)
2189desired.
2190
2191More commonly, an application wants to run an entirely new POE::Kernel
2192instance in the child process.  This is supported by first stop()ping
2193the copied instance, starting one or more new sessions, and calling
2194run() again.  For example:
2195
2196  Program => sub {
2197    # Wipe the existing POE::Kernel clean.
2198    $poe_kernel->stop();
2199
2200    # Start a new session, or more.
2201    POE::Session->create(
2202      ...
2203    );
2204
2205    # Run the new sessions.
2206    POE::Kernel->run();
2207  }
2208
2209Strange things are bound to happen if the program does not call
2210L<POE::Kernel/stop> before L<POE::Kernel/run>.  However this is
2211vaguely supported in case it's the right thing to do at the time.
2212
2213=head1 SEE ALSO
2214
2215L<POE::Wheel> describes wheels in general.
2216
2217The SEE ALSO section in L<POE> contains a table of contents covering
2218the entire POE distribution.
2219
2220=head1 CAVEATS & TODOS
2221
2222POE::Wheel::Run's constructor should emit proper events when it fails.
2223Instead, it just dies, carps or croaks.  This isn't necessarily bad; a
2224program can trap the death in new() and move on.
2225
2226Priority is a delta, not an absolute niceness value.
2227
2228It might be nice to specify User by name rather than just UID.
2229
2230It might be nice to specify Group by name rather than just GID.
2231
2232POE::Pipe::OneWay and Two::Way don't require the rest of POE.  They
2233should be spun off into a separate distribution for everyone to enjoy.
2234
2235If StdinFilter and StdoutFilter seem backwards, remember that it's the
2236filters for the child process.  StdinFilter is the one that dictates
2237what the child receives on STDIN.  StdoutFilter tells the parent how
2238to parse the child's STDOUT.
2239
2240=head1 AUTHORS & COPYRIGHTS
2241
2242Please see L<POE> for more information about authors and contributors.
2243
2244=cut
2245
2246# rocco // vim: ts=2 sw=2 expandtab
2247# TODO - Edit.
2248