Job.pm 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. # ex:ts=8 sw=4:
  2. # $OpenBSD: Job.pm,v 1.11 2017/04/14 16:43:40 espie Exp $
  3. #
  4. # Copyright (c) 2010-2013 Marc Espie <espie@openbsd.org>
  5. #
  6. # Permission to use, copy, modify, and distribute this software for any
  7. # purpose with or without fee is hereby granted, provided that the above
  8. # copyright notice and this permission notice appear in all copies.
  9. #
  10. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  11. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  12. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  13. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  14. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  15. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  16. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  17. use strict;
  18. use warnings;
  19. use DPB::Util;
  20. # a "job" is the actual stuff a core runs at some point.
  21. # it's mostly an abstract class here... it's organized
  22. # as a list of tasks, with a finalization routine
  23. package DPB::Task;
  24. sub end
  25. {
  26. }
  27. sub code
  28. {
  29. my $self = shift;
  30. return $self->{code};
  31. }
  32. # no name by default, just display the object
  33. sub name
  34. {
  35. return shift;
  36. }
  37. sub new
  38. {
  39. my ($class, $code) = @_;
  40. bless {code => $code}, $class;
  41. }
  42. sub run
  43. {
  44. my ($self, $core) = @_;
  45. &{$self->code($core)}($core->shell);
  46. }
  47. sub process
  48. {
  49. my ($self, $core) = @_;
  50. }
  51. sub finalize
  52. {
  53. my ($self, $core) = @_;
  54. return $core->{status} == 0;
  55. }
  56. sub redirect
  57. {
  58. my ($self, $log) = @_;
  59. close STDOUT;
  60. open STDOUT, '>>', $log or DPB::Util->die_bang("Can't write to $log");
  61. close STDERR;
  62. open STDERR, '>&STDOUT' or DPB::Util->die_bang("bad redirect");
  63. }
  64. sub redirect_fh
  65. {
  66. my ($self, $fh, $log) = @_;
  67. close STDOUT;
  68. open STDOUT, '>&', $fh or DPB::Util->die_bang("Can't write to $log");
  69. close STDERR;
  70. open STDERR, '>&STDOUT' or DPB::Util->die_bang("bad redirect");
  71. }
  72. package DPB::Task::Pipe;
  73. our @ISA =qw(DPB::Task);
  74. sub fork
  75. {
  76. my $self = shift;
  77. open($self->{fh}, "-|");
  78. }
  79. sub end
  80. {
  81. my $self = shift;
  82. close($self->{fh});
  83. }
  84. package DPB::Task::Fork;
  85. our @ISA =qw(DPB::Task);
  86. sub fork
  87. {
  88. CORE::fork();
  89. }
  90. package DPB::Job;
  91. sub next_task
  92. {
  93. my ($self, $core) = @_;
  94. return shift @{$self->{tasks}};
  95. }
  96. sub name
  97. {
  98. my $self = shift;
  99. return $self->{name};
  100. }
  101. sub debug_dump
  102. {
  103. my $self = shift;
  104. return $self->{name};
  105. }
  106. sub finalize
  107. {
  108. }
  109. sub watched
  110. {
  111. my $self = shift;
  112. return $self->{status};
  113. }
  114. # abstract method, to be used by jobs that have actual watch limits
  115. sub kill_on_timeout
  116. {
  117. my ($self, $diff, $core, $msg) = @_;
  118. my $to = $self->get_timeout($core);
  119. return $msg if !defined $to || $diff <= $to;
  120. local $> = 0; # XXX switch to root, we don't know for sure which
  121. # user owns the pid (not really an issue)
  122. kill 9, $core->{pid};
  123. return $self->{stuck} = "KILLED: $self->{current} stuck at $msg";
  124. }
  125. sub add_tasks
  126. {
  127. my ($self, @tasks) = @_;
  128. push(@{$self->{tasks}}, @tasks);
  129. }
  130. sub replace_tasks
  131. {
  132. my ($self, @tasks) = @_;
  133. $self->{tasks} = [];
  134. push(@{$self->{tasks}}, @tasks);
  135. }
  136. sub insert_tasks
  137. {
  138. my ($self, @tasks) = @_;
  139. unshift(@{$self->{tasks}}, @tasks);
  140. }
  141. sub really_watch
  142. {
  143. }
  144. sub new
  145. {
  146. my ($class, $name) = @_;
  147. bless {name => $name, status => ""}, $class;
  148. }
  149. sub set_status
  150. {
  151. my ($self, $status) = @_;
  152. $self->{status} = $status;
  153. }
  154. package DPB::Job::Normal;
  155. our @ISA =qw(DPB::Job);
  156. sub new
  157. {
  158. my ($class, $code, $endcode, $name) = @_;
  159. my $o = $class->SUPER::new($name);
  160. $o->{tasks} = [DPB::Task::Fork->new($code)];
  161. $o->{endcode} = $endcode;
  162. return $o;
  163. }
  164. sub finalize
  165. {
  166. my $self = shift;
  167. &{$self->{endcode}}(@_);
  168. }
  169. package DPB::Job::Infinite;
  170. our @ISA = qw(DPB::Job);
  171. sub next_task
  172. {
  173. my $job = shift;
  174. return $job->{task};
  175. }
  176. sub new
  177. {
  178. my ($class, $task, $name) = @_;
  179. my $o = $class->SUPER::new($name);
  180. $o->{task} = $task;
  181. return $o;
  182. }
  183. package DPB::Job::Pipe;
  184. our @ISA = qw(DPB::Job);
  185. sub new
  186. {
  187. my ($class, $code, $name) = @_;
  188. my $o = $class->SUPER::new($name);
  189. $o->{tasks} = [DPB::Task::Pipe->new($code)];
  190. return $o;
  191. }
  192. 1;