/[cvs]/joko/TestArea/perl/runtime/POE/jobs-tasks/run.pl
ViewVC logotype

Annotation of /joko/TestArea/perl/runtime/POE/jobs-tasks/run.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Sun May 11 21:48:52 2003 UTC (21 years, 4 months ago) by joko
Branch: MAIN
CVS Tags: HEAD
File MIME type: text/plain
initial commit

1 joko 1.1 #!/usr/bin/perl
2     # $Id$
3    
4     # This program manages a child process started with POE::Wheel::Run.
5     # Wheel::Run is a lot like IPC::Run but event driven. Because it
6     # doesn't block, though, it can be instantiated several times to drive
7     # many child processes.
8     #
9     # This sample runs a single process, nethack, as its test program. It
10     # adds two "features" to stock nethack:
11     #
12     # 1. It changes all "@" characters to random colors. It's annoying,
13     # but it lets you know the program's working.
14     #
15     # 2. Ctrl+C sends a string of random movement commands to the child
16     # process. This causes your player to go a little berzerk.
17    
18     use warnings;
19     use strict;
20    
21     sub PROGRAM () { "nethack" }
22    
23     use POSIX;
24     use POE qw( Wheel::ReadWrite Wheel::Run Filter::Stream );
25    
26     ### Handle the _start event. This sets things in motion.
27    
28     sub handle_start {
29     my ( $kernel, $heap ) = @_[ KERNEL, HEAP ];
30    
31     # Set a signal handler.
32    
33     $kernel->sig( CHLD => "got_sigchld" );
34    
35     # Save the original terminal settings so they can be restored later.
36    
37     $heap->{stdin_tio} = POSIX::Termios->new();
38     $heap->{stdin_tio}->getattr(0);
39     $heap->{stdout_tio} = POSIX::Termios->new();
40     $heap->{stdout_tio}->getattr(1);
41     $heap->{stderr_tio} = POSIX::Termios->new();
42     $heap->{stderr_tio}->getattr(2);
43    
44     # Put the terminal into raw input mode. Otherwise discrete
45     # keystrokes will not be read immediately.
46    
47     my $tio = POSIX::Termios->new();
48     $tio->getattr(0);
49     my $lflag = $tio->getlflag;
50     $lflag &= ~( ECHO | ECHOE | ECHOK | ECHONL | ICANON | IEXTEN | ISIG );
51     $tio->setlflag($lflag);
52     my $iflag = $tio->getiflag;
53     $iflag &= ~( BRKINT | INPCK | ISTRIP | IXON );
54     $tio->setiflag($iflag);
55     my $cflag = $tio->getcflag;
56     $cflag &= ~( CSIZE | PARENB );
57     $tio->setcflag($cflag);
58     $tio->setattr( 0, TCSANOW );
59    
60     # Start the terminal reader/writer.
61    
62     $heap->{stdio} = POE::Wheel::ReadWrite->new
63     ( InputHandle => \*STDIN,
64     OutputHandle => \*STDOUT,
65     InputEvent => "got_terminal_stdin",
66     Filter => POE::Filter::Stream->new(),
67     );
68    
69     # Start the asynchronous child process.
70    
71     $heap->{program} = POE::Wheel::Run->new
72     ( Program => PROGRAM,
73     Conduit => "pty",
74     StdoutEvent => "got_child_stdout",
75     Filter => POE::Filter::Stream->new(),
76     );
77     }
78    
79     ### Handle the _stop event. This restores the original terminal
80     ### settings when we're done. That's very important.
81    
82     sub handle_stop {
83     my $heap = $_[HEAP];
84     $heap->{stdin_tio}->setattr( 0, TCSANOW );
85     $heap->{stdout_tio}->setattr( 1, TCSANOW );
86     $heap->{stderr_tio}->setattr( 2, TCSANOW );
87     }
88    
89     ### Handle terminal STDIN. Send it to the background program's STDIN.
90     ### If the user presses ^C, then also go berserk a little.
91    
92     sub handle_terminal_stdin {
93     my ( $heap, $input ) = @_[ HEAP, ARG0 ];
94    
95     while ( $input =~ m/\003/g ) {
96     my $count = int( 5 + rand(10) );
97     my $random_walk = '';
98     $random_walk .= int( rand(9) + 1 ) while $count--;
99     $random_walk =~ tr[5][]d;
100     substr( $input, pos($input) - 1, 1 ) = $random_walk;
101     }
102    
103     $heap->{program}->put($input);
104     }
105    
106     ### Handle STDOUT from the child program. Send it to the terminal's
107     ### STDOUT. Oh, and do something silly like change the foreground
108     ### color of "@" characters to something random. :)
109    
110     sub handle_child_stdout {
111     my ( $heap, $input ) = @_[ HEAP, ARG0 ];
112     my $color = int rand 8;
113     $input =~ s/\@/\e[3${color}m\@\e[0m/g;
114     $heap->{stdio}->put($input);
115     }
116    
117     ### Handle SIGCHLD. Shut down if the exiting child process was the
118     ### one we've been managing.
119    
120     sub handle_sigchld {
121     my ( $heap, $child_pid ) = @_[ HEAP, ARG1 ];
122     if ( $child_pid == $heap->{program}->PID ) {
123     delete $heap->{program};
124     delete $heap->{stdio};
125     }
126     return 0;
127     }
128    
129     ### Start a session to encapsulate the previous features.
130    
131     POE::Session->create
132     ( inline_states =>
133     { _start => \&handle_start,
134     _stop => \&handle_stop,
135     got_terminal_stdin => \&handle_terminal_stdin,
136     got_child_stdout => \&handle_child_stdout,
137     got_sigchld => \&handle_sigchld,
138     },
139     );
140    
141     ### Start POE's main loop, which runs the session until it's done.
142    
143     $poe_kernel->run();
144     exit 0;

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed