… | |
… | |
31 | use common::sense; |
31 | use common::sense; |
32 | |
32 | |
33 | use Carp (); |
33 | use Carp (); |
34 | |
34 | |
35 | use AnyEvent; |
35 | use AnyEvent; |
|
|
36 | use AnyEvent::Util; |
|
|
37 | |
36 | use AnyEvent::MP::Config; |
38 | use AnyEvent::MP::Config; |
37 | use AnyEvent::MP; |
39 | use AnyEvent::MP; |
38 | |
|
|
39 | sub run_cmd { |
|
|
40 | my $cmd = shift; |
|
|
41 | |
|
|
42 | require POSIX; |
|
|
43 | |
|
|
44 | local $^F = 1023; #d# |
|
|
45 | |
|
|
46 | my $cv = AE::cv; |
|
|
47 | |
|
|
48 | my %redir; |
|
|
49 | my @exe; |
|
|
50 | |
|
|
51 | while (@_) { |
|
|
52 | my $type = shift; |
|
|
53 | |
|
|
54 | my $fd = $type =~ s/^(\d+)// ? $1 : undef; |
|
|
55 | |
|
|
56 | if ($type eq ">") { |
|
|
57 | my ($pr, $pw) = AnyEvent::Util::portable_pipe; |
|
|
58 | my $cb = shift; |
|
|
59 | |
|
|
60 | $cv->begin; |
|
|
61 | my $w; $w = AE::io $pr, 0, |
|
|
62 | "SCALAR" eq ref $cb |
|
|
63 | ? sub { |
|
|
64 | sysread $pr, $$cb, 8192, length $$cb |
|
|
65 | and return; |
|
|
66 | undef $w; $cv->end; |
|
|
67 | } |
|
|
68 | : sub { |
|
|
69 | my $buf; |
|
|
70 | sysread $pr, $buf, 8192 |
|
|
71 | and return $cb->($buf); |
|
|
72 | undef $w; $cv->end; |
|
|
73 | } |
|
|
74 | ; |
|
|
75 | $redir{defined $fd ? $fd : 1} = $pw; |
|
|
76 | |
|
|
77 | } elsif ($type eq "<") { |
|
|
78 | my ($pr, $pw) = AnyEvent::Util::portable_pipe; |
|
|
79 | my $cb = shift; |
|
|
80 | |
|
|
81 | #TODO |
|
|
82 | # $cv->begin; |
|
|
83 | # my $w; $w = AE::io $pw, 0, |
|
|
84 | # "SCALAR" eq ref $cb |
|
|
85 | # ? sub { |
|
|
86 | # my $len = syswrite $pr, $$cb, 8192, length $$cb |
|
|
87 | # and return; |
|
|
88 | # undef $w; $cv->end; |
|
|
89 | # } |
|
|
90 | # : sub { |
|
|
91 | # my $buf; |
|
|
92 | # sysread $pr, $buf, 8192 |
|
|
93 | # and return $cb->($buf); |
|
|
94 | # undef $w; $cv->end; |
|
|
95 | # } |
|
|
96 | # ; |
|
|
97 | # $redir{defined $fd ? $fd : 0} = $pr; |
|
|
98 | |
|
|
99 | } elsif ($type =~ s/^>//) { |
|
|
100 | push @exe, sub { |
|
|
101 | open my $fh, ">", $type |
|
|
102 | or POSIX::_exit (125); |
|
|
103 | $redir{defined $fd ? $fd : 1} = $fh; |
|
|
104 | }; |
|
|
105 | |
|
|
106 | } elsif ($type =~ s/^<//) { |
|
|
107 | push @exe, sub { |
|
|
108 | open my $fh, "<", $type |
|
|
109 | or POSIX::_exit (125); |
|
|
110 | $redir{defined $fd ? $fd : 0} = $fh; |
|
|
111 | }; |
|
|
112 | } |
|
|
113 | } |
|
|
114 | |
|
|
115 | my $pid = fork; |
|
|
116 | |
|
|
117 | defined $pid |
|
|
118 | or Carp::croak "fork: $!"; |
|
|
119 | |
|
|
120 | unless ($pid) { |
|
|
121 | # step 1, execute |
|
|
122 | $_->() for @exe; |
|
|
123 | |
|
|
124 | # step 2, move any existing fd's out of the way |
|
|
125 | my @oldfh; |
|
|
126 | for my $fh (values %redir) { |
|
|
127 | push @oldfh, $fh; |
|
|
128 | $fh = fileno $fh; |
|
|
129 | |
|
|
130 | defined ($fh = POSIX::dup ($fh)) or POSIX::_exit (124) |
|
|
131 | while exists $redir{$fh}; |
|
|
132 | } |
|
|
133 | |
|
|
134 | # step 3, execute redirects |
|
|
135 | while (my ($k, $v) = each %redir) { |
|
|
136 | defined POSIX::dup2 ($v, $k) |
|
|
137 | or POSIX::_exit (123); |
|
|
138 | } |
|
|
139 | |
|
|
140 | # step 4, close everything else |
|
|
141 | for (3..1023) { #TODO |
|
|
142 | POSIX::close ($_) |
|
|
143 | unless exists $redir{$_}; |
|
|
144 | } |
|
|
145 | |
|
|
146 | exec @$cmd; |
|
|
147 | |
|
|
148 | POSIX::_exit (126); |
|
|
149 | } |
|
|
150 | |
|
|
151 | close $_ for values %redir; |
|
|
152 | |
|
|
153 | my $status; |
|
|
154 | $cv->begin (sub { shift->send ($status) }); |
|
|
155 | my $cw; $cw = AE::child $pid, sub { |
|
|
156 | $status = $_[1]; |
|
|
157 | undef $cw; $cv->end; |
|
|
158 | }; |
|
|
159 | |
|
|
160 | $cv |
|
|
161 | } |
|
|
162 | |
40 | |
163 | sub my_run_cmd { |
41 | sub my_run_cmd { |
164 | my ($cmd) = @_; |
42 | my ($cmd) = @_; |
165 | |
43 | |
166 | my $cv = &run_cmd; |
44 | my $cv = &run_cmd; |
… | |
… | |
174 | my_run_cmd [qw(openssl req |
52 | my_run_cmd [qw(openssl req |
175 | -new -nodes -x509 -days 3650 |
53 | -new -nodes -x509 -days 3650 |
176 | -newkey rsa:2048 -keyout /dev/fd/3 |
54 | -newkey rsa:2048 -keyout /dev/fd/3 |
177 | -batch -subj /CN=AnyEvent::MP |
55 | -batch -subj /CN=AnyEvent::MP |
178 | )], |
56 | )], |
179 | "</dev/null", |
57 | "</", "dev/null", |
180 | ">" , \my $cert, |
58 | ">" , \my $cert, |
181 | "3>", \my $key, |
59 | "3>", \my $key, |
182 | "2>/dev/null"; |
60 | "2>", "/dev/null"; |
183 | |
61 | |
184 | "$cert$key" |
62 | "$cert$key" |
185 | } |
63 | } |
186 | |
64 | |
187 | our $cfg = \%AnyEvent::MP::Config::CFG; |
65 | our $cfg = \%AnyEvent::MP::Config::CFG; |