Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | package Psh::Joblist; |
2 | ||
3 | use strict; | |
4 | require Psh::OS; | |
5 | ||
6 | my @jobs_order=(); | |
7 | my %jobs_list=(); | |
8 | ||
9 | sub create_job { | |
10 | my ($pid, $call, $assoc_obj) = @_; | |
11 | ||
12 | my $job = new Psh::Job( $pid, $call, $assoc_obj); | |
13 | $jobs_list{$pid}=$job; | |
14 | push(@jobs_order,$job); | |
15 | return $job; | |
16 | } | |
17 | ||
18 | sub delete_job { | |
19 | my ($pid) = @_; | |
20 | ||
21 | my $job= $jobs_list{$pid}; | |
22 | return if !defined($job); | |
23 | ||
24 | delete $jobs_list{$pid}; | |
25 | my $i; | |
26 | for($i=0; $i <= $#jobs_order; $i++) { | |
27 | last if( $jobs_order[$i]==$job); | |
28 | } | |
29 | ||
30 | splice( @jobs_order, $i, 1); | |
31 | } | |
32 | ||
33 | sub job_exists { | |
34 | my $pid= shift; | |
35 | ||
36 | return exists($jobs_list{$pid}); | |
37 | } | |
38 | ||
39 | sub get_job { | |
40 | my $pid= shift; | |
41 | return $jobs_list{$pid}; | |
42 | } | |
43 | ||
44 | sub list_jobs { | |
45 | return @jobs_order; | |
46 | } | |
47 | ||
48 | sub get_job_number { | |
49 | my $pid= shift; | |
50 | ||
51 | for( my $i=0; $i<=$#jobs_order; $i++) { | |
52 | return $i+1 if( $jobs_order[$i]->{pid}==$pid); | |
53 | } | |
54 | return -1; | |
55 | } | |
56 | ||
57 | # | |
58 | # $pid=Psh::Joblist::find_job([$jobnumber]) | |
59 | # Finds either the job with the specified job number | |
60 | # or the highest numbered not running job and returns | |
61 | # the job or undef is none is found | |
62 | # | |
63 | sub find_job { | |
64 | my $job_to_start= shift; | |
65 | ||
66 | return $jobs_order[$job_to_start] if defined( $job_to_start); | |
67 | ||
68 | for (my $i = $#jobs_order; $i >= 0; $i--) { | |
69 | my $job = $jobs_order[$i]; | |
70 | ||
71 | if(!$job->{running}) { | |
72 | return wantarray?($i,$job):$job; | |
73 | } | |
74 | } | |
75 | return undef; | |
76 | } | |
77 | ||
78 | sub find_last_with_name { | |
79 | my ($name, $runningflag) = @_; | |
80 | enumerate(); | |
81 | my $index=0; | |
82 | while( my $job= Psh::Joblist::each()) { | |
83 | next if $runningflag && $job->{running}; | |
84 | my $call= $job->{call}; | |
85 | if ($call=~ m:([^/\s]+)\s*: ) { | |
86 | $call= $1; | |
87 | } elsif( $call=~ m:/([^/\s]+)\s+.*$: ) { | |
88 | $call= $1; | |
89 | } elsif ( $call=~ m:^([^/\s]+): ) { | |
90 | $call= $1; | |
91 | } | |
92 | if( $call eq $name) { | |
93 | return wantarray?($index,$job->{pid},$job->{call}):$index; | |
94 | } | |
95 | $index++; | |
96 | } | |
97 | return wantarray?():undef; | |
98 | } | |
99 | ||
100 | { | |
101 | my $pointer; | |
102 | ||
103 | # | |
104 | # Resets the enumeration counter for access using "each" | |
105 | # | |
106 | sub enumerate { | |
107 | $pointer=0; | |
108 | } | |
109 | ||
110 | # | |
111 | # Returns the next job | |
112 | # | |
113 | sub each { | |
114 | if ($pointer <= $#jobs_order) { | |
115 | return $jobs_order[$pointer++]; | |
116 | } | |
117 | return undef; | |
118 | } | |
119 | } | |
120 | ||
121 | package Psh::Job; | |
122 | ||
123 | # | |
124 | # $job= new Psh::Job( pid, call); | |
125 | # Creates a new Job object | |
126 | # pid is the pid of the object | |
127 | # call is the name of the executed command | |
128 | # | |
129 | sub new { | |
130 | my ( $class, $pid, $call, $assoc_obj ) = @_; | |
131 | my $self = {}; | |
132 | bless $self, $class; | |
133 | $self->{pid}=$pid; | |
134 | $self->{call}=$call; | |
135 | $self->{running}=1; | |
136 | $self->{assoc_obj}=$assoc_obj; | |
137 | return $self; | |
138 | } | |
139 | ||
140 | # | |
141 | # $job->run; | |
142 | # Sends SIGCONT to the job and records it running | |
143 | # | |
144 | sub continue { | |
145 | my $self= shift; | |
146 | ||
147 | # minus sign to wake up the whole group of the child: | |
148 | if( Psh::OS::has_job_control()) { | |
149 | Psh::OS::resume_job($self); | |
150 | } | |
151 | $self->{running}=1; | |
152 | } | |
153 | ||
154 | 1; | |
155 | __END__ | |
156 | ||
157 | =head1 NAME | |
158 | ||
159 | Psh::Joblist - A data structure suitable for handling job lists like bash's | |
160 | ||
161 | =head1 SYNOPSIS | |
162 | ||
163 | use Psh::Joblist; | |
164 | ||
165 | $job = Psh::Joblist::create_job($pid,$displayed_command); | |
166 | ||
167 | Psh::Joblist::delete_job($pid); | |
168 | ||
169 | $job = Psh::Joblist::get_job($pid); | |
170 | ||
171 | $flag = Psh::Joblist::job_exists($pid); | |
172 | ||
173 | $index = Psh::Joblist::get_job_number($pid); | |
174 | ||
175 | $job = Psh::Joblist::find_job(); | |
176 | $job = Psh::Joblist::find_job($index); | |
177 | ||
178 | Psh::Joblist::enumerate(); | |
179 | while( $job= Psh::Joblist::each()) { ... } | |
180 | ||
181 | =head1 DESCRIPTION | |
182 | ||
183 | Read the source ;-) | |
184 | ||
185 | =head1 AUTHOR | |
186 | ||
187 | Markus Peter (warp@spin.de) | |
188 | ||
189 | =cut |