proc-wait3 1.9.1 → 1.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +5 -5
- data/CHANGES.md +9 -0
- data/README.md +32 -0
- data/Rakefile +6 -3
- data/examples/example_getrusage.rb +5 -3
- data/examples/example_pause.rb +7 -5
- data/examples/example_wait3.rb +5 -2
- data/examples/example_wait4.rb +5 -2
- data/examples/example_waitid.rb +5 -2
- data/ext/extconf.rb +6 -1
- data/ext/proc/wait3.c +14 -2
- data/lib/proc-wait3.rb +2 -0
- data/proc-wait3.gemspec +6 -3
- data/spec/proc_wait3_spec.rb +121 -140
- data/spec/spec_helper.rb +16 -0
- data.tar.gz.sig +0 -0
- metadata +36 -6
- metadata.gz.sig +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13f18822c2208220d663b7ddf89cd3ef3763185621f23ed81bf6dced9beb8b76
|
|
4
|
+
data.tar.gz: 6a82d5550af63215cf4e62b3e390865f5f08e3b3ec30be50128791bf8b9a45a1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b015e49e3c835d2855552e3d54f2fdf047d11889f5db55ac2db246d277c9fe3ad1135e73e6cb01a0caa5d88bd93c3de361670d74dc78b3a5139c10ea86db46c7
|
|
7
|
+
data.tar.gz: f0134f481fa6f8d3cdbdcef1e6f380727afb894e1ed754bd77b568f3a0d43118a3c71aa93f68ea7d96b15768f569fa63199782f91c5c2d729c9efc47cdb0d0ab
|
checksums.yaml.gz.sig
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
e��)#
|
|
2
|
+
�P�H�s�/w��"�
|
|
3
|
+
���|.6;_i�<;����;�"Zl{����u_dE�oM������ǑW�X��_&�i*\ak�l����GoMx|y�"@���|��4G�����jF�ح3���=��R�YK
|
|
4
|
+
�Vo6�.�k0Z�����E�4Z�JJ�G�ڝ"�c�8���s�[<~Vw�a-�NF��+ {�쌌��s{�
|
|
5
|
+
#����Qw��4w�j
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 1.9.3 - 4-May-2024
|
|
2
|
+
* Some internal refactoring where I bzero C structs before using them.
|
|
3
|
+
|
|
4
|
+
## 1.9.2 - 21-Apr-2024
|
|
5
|
+
* Added the P_JAILID constant for BSD platforms.
|
|
6
|
+
* Added some notes to the README for coping with EINTR.
|
|
7
|
+
* Added rubocop and rubocop-rspec as dev dependencies and did
|
|
8
|
+
some general rubocop cleanup.
|
|
9
|
+
|
|
1
10
|
## 1.9.1 - 8-Feb-2024
|
|
2
11
|
* Replace sigset with sigaction in the pause method.
|
|
3
12
|
* General cleanup and platform handling updates.
|
data/README.md
CHANGED
|
@@ -38,6 +38,38 @@ These methods may fail in conjunction with `fork` with `Errno::EINTR` unless
|
|
|
38
38
|
you pass the WNOHANG flag, or explicitly ignore the `SIGCHLD` signal. Ruby's
|
|
39
39
|
own `wait` methods appear to essentially be doing that behind the scenes.
|
|
40
40
|
|
|
41
|
+
Note that on some platforms just setting a `SIGCHLD` handler may not be
|
|
42
|
+
enough to prevent an `Errno::EINTR` from occuring since you can never be sure
|
|
43
|
+
what signal it's going to receive. Since this appears to be coming from the
|
|
44
|
+
guts of the Ruby core code itself IMO, it's somewhat out of my hands, but it's
|
|
45
|
+
not impossible to deal with.
|
|
46
|
+
|
|
47
|
+
A typical idiom would be to simulate the `TEMP_FAILURE_RETRY` macro that the GNU
|
|
48
|
+
library provides. This macro wraps a given function and retries it so long as
|
|
49
|
+
it doesn't fail, or the only failure is an `EINTR`. I've chosen not to integrate
|
|
50
|
+
this into the code directly (yet), but you can simulate it like so:
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
require 'English'
|
|
54
|
+
|
|
55
|
+
begin
|
|
56
|
+
pid = fork{ sleep 1; exit 2 }
|
|
57
|
+
Process.wait3
|
|
58
|
+
rescue Errno::EINTR
|
|
59
|
+
retry
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
p $CHILD_STATUS
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For more information please see:
|
|
66
|
+
|
|
67
|
+
https://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Interrupted-Primitives.html
|
|
68
|
+
|
|
69
|
+
BSD provides another approach using sigaction handlers + `SA_RESTART`, but it requires knowing
|
|
70
|
+
the signal type in advance. So, unless you want to apply the same handler to *every* type of
|
|
71
|
+
signal, I don't find it especially useful.
|
|
72
|
+
|
|
41
73
|
## Integration with Ruby's process.c
|
|
42
74
|
I considered simply providing a patch to the core process.c file, but I
|
|
43
75
|
decided against it for two reasons. First, I wanted to get something
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'rake'
|
|
2
2
|
require 'rake/clean'
|
|
3
3
|
require 'rspec/core/rake_task'
|
|
4
|
+
require 'rubocop/rake_task'
|
|
4
5
|
require 'fileutils'
|
|
5
6
|
require 'rbconfig'
|
|
6
7
|
include RbConfig
|
|
@@ -27,7 +28,7 @@ task :build => [:clean] do |t|
|
|
|
27
28
|
end
|
|
28
29
|
|
|
29
30
|
namespace :gem do
|
|
30
|
-
desc
|
|
31
|
+
desc 'Create the proc-wait3 gem'
|
|
31
32
|
task :create => [:clean] do
|
|
32
33
|
require 'rubygems/package'
|
|
33
34
|
spec = Gem::Specification.load('proc-wait3.gemspec')
|
|
@@ -35,7 +36,7 @@ namespace :gem do
|
|
|
35
36
|
Gem::Package.build(spec)
|
|
36
37
|
end
|
|
37
38
|
|
|
38
|
-
desc
|
|
39
|
+
desc 'Install the proc-wait3 gem'
|
|
39
40
|
task :install => [:create] do |t|
|
|
40
41
|
file = Dir['*.gem'].first
|
|
41
42
|
sh "gem install -l #{file}"
|
|
@@ -69,9 +70,11 @@ namespace :example do
|
|
|
69
70
|
end
|
|
70
71
|
end
|
|
71
72
|
|
|
72
|
-
desc
|
|
73
|
+
desc 'Run the test suite'
|
|
73
74
|
RSpec::Core::RakeTask.new(:spec) do |t|
|
|
74
75
|
t.rspec_opts = '-Iext'
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
task :default => [:build, :spec]
|
|
79
|
+
|
|
80
|
+
RuboCop::RakeTask.new
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
########################################################################
|
|
2
4
|
# example_getrusage.rb
|
|
3
5
|
#
|
|
@@ -11,7 +13,7 @@ require 'pp'
|
|
|
11
13
|
|
|
12
14
|
# Show resource stats for this process for 30 seconds
|
|
13
15
|
10.times do
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
pp Process.getrusage
|
|
17
|
+
puts '=' * 50
|
|
18
|
+
sleep 3
|
|
17
19
|
end
|
data/examples/example_pause.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
#######################################################################
|
|
2
4
|
# example_pause.rb
|
|
3
5
|
#
|
|
@@ -9,13 +11,13 @@
|
|
|
9
11
|
require 'rbconfig'
|
|
10
12
|
require 'proc/wait3'
|
|
11
13
|
|
|
12
|
-
puts
|
|
14
|
+
puts 'Pausing. Hit Ctrl-C to continue.'
|
|
13
15
|
|
|
14
16
|
if RbConfig::CONFIG['host_os'] =~ /linux|darwin/i
|
|
15
|
-
|
|
17
|
+
Process.pause(2)
|
|
16
18
|
else
|
|
17
|
-
|
|
19
|
+
Process.pause('INT')
|
|
18
20
|
end
|
|
19
21
|
|
|
20
|
-
puts
|
|
21
|
-
puts
|
|
22
|
+
puts 'Hey, thanks for hitting Ctrl-C. Continuing...'
|
|
23
|
+
puts 'Done'
|
data/examples/example_wait3.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
#######################################################################
|
|
2
4
|
# example_wait3.rb
|
|
3
5
|
#
|
|
@@ -6,10 +8,11 @@
|
|
|
6
8
|
#
|
|
7
9
|
# Modify as you see fit.
|
|
8
10
|
#######################################################################
|
|
11
|
+
require 'English'
|
|
9
12
|
require 'proc/wait3'
|
|
10
13
|
|
|
11
|
-
pid = fork{ sleep 1; exit 2 }
|
|
14
|
+
pid = fork { sleep 1; exit 2 }
|
|
12
15
|
|
|
13
16
|
p Time.now
|
|
14
17
|
Process.wait3
|
|
15
|
-
p
|
|
18
|
+
p $CHILD_STATUS
|
data/examples/example_wait4.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
#######################################################################
|
|
2
4
|
# example_wait4.rb
|
|
3
5
|
#
|
|
@@ -6,9 +8,10 @@
|
|
|
6
8
|
#
|
|
7
9
|
# Modify as you see fit.
|
|
8
10
|
#######################################################################
|
|
11
|
+
require 'English'
|
|
9
12
|
require 'proc/wait3'
|
|
10
13
|
|
|
11
|
-
pid = fork{ sleep 2 }
|
|
14
|
+
pid = fork { sleep 2 }
|
|
12
15
|
p Time.now
|
|
13
16
|
Process.wait4(pid, Process::WUNTRACED)
|
|
14
|
-
p
|
|
17
|
+
p $CHILD_STATUS
|
data/examples/example_waitid.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
#######################################################################
|
|
2
4
|
# example_waitid.rb
|
|
3
5
|
#
|
|
@@ -6,9 +8,10 @@
|
|
|
6
8
|
#
|
|
7
9
|
# Modify as you see fit.
|
|
8
10
|
#######################################################################
|
|
11
|
+
require 'English'
|
|
9
12
|
require 'proc/wait3'
|
|
10
13
|
|
|
11
|
-
pid = fork{ sleep 2 }
|
|
14
|
+
pid = fork { sleep 2 }
|
|
12
15
|
p Time.now
|
|
13
16
|
Process.waitid(Process::P_PID, pid, Process::WEXITED)
|
|
14
|
-
p
|
|
17
|
+
p $CHILD_STATUS
|
data/ext/extconf.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
########################################################
|
|
2
4
|
# Use the mkmf.rb file that I provide, so I can use the
|
|
3
5
|
# have_enum_member method
|
|
@@ -12,7 +14,7 @@ have_header('sys/wait.h')
|
|
|
12
14
|
|
|
13
15
|
# wait3 is mandatory.
|
|
14
16
|
unless have_func('wait3')
|
|
15
|
-
|
|
17
|
+
warn 'wait3() function not found'
|
|
16
18
|
exit
|
|
17
19
|
end
|
|
18
20
|
|
|
@@ -68,4 +70,7 @@ have_const('P_TASKID', 'signal.h')
|
|
|
68
70
|
# RUSAGE_THREAD is Linux-specific
|
|
69
71
|
have_const('RUSAGE_THREAD', 'sys/resource.h')
|
|
70
72
|
|
|
73
|
+
# BSD
|
|
74
|
+
have_const('P_JAILID', 'sys/wait.h')
|
|
75
|
+
|
|
71
76
|
create_makefile('proc/wait3', 'proc')
|
data/ext/proc/wait3.c
CHANGED
|
@@ -154,6 +154,7 @@ static VALUE proc_wait3(int argc, VALUE *argv, VALUE mod){
|
|
|
154
154
|
flags = NUM2INT(v_flags);
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
bzero(&r, sizeof(r));
|
|
157
158
|
pid = wait3(&status, flags, &r);
|
|
158
159
|
|
|
159
160
|
if(pid < 0){
|
|
@@ -226,6 +227,7 @@ static VALUE proc_wait4(int argc, VALUE *argv, VALUE mod){
|
|
|
226
227
|
if(RTEST(v_flags))
|
|
227
228
|
flags = NUM2INT(v_flags);
|
|
228
229
|
|
|
230
|
+
bzero(&r, sizeof(r));
|
|
229
231
|
pid = wait4(pid, &status, flags, &r);
|
|
230
232
|
|
|
231
233
|
if(pid < 0){
|
|
@@ -587,6 +589,9 @@ static VALUE proc_pause(int argc, VALUE* argv, VALUE mod){
|
|
|
587
589
|
int signum;
|
|
588
590
|
struct sigaction act, sa;
|
|
589
591
|
|
|
592
|
+
bzero(&act, sizeof(act));
|
|
593
|
+
bzero(&sa, sizeof(sa));
|
|
594
|
+
|
|
590
595
|
for(i = 0; i < len; i++){
|
|
591
596
|
v_val = rb_ary_shift(v_signals);
|
|
592
597
|
|
|
@@ -752,6 +757,8 @@ static VALUE proc_getrusage(int argc, VALUE* argv, VALUE mod){
|
|
|
752
757
|
else if(RTEST(v_children))
|
|
753
758
|
who = RUSAGE_CHILDREN;
|
|
754
759
|
|
|
760
|
+
bzero(&r, sizeof(r));
|
|
761
|
+
|
|
755
762
|
if(getrusage(who,&r) == -1)
|
|
756
763
|
rb_sys_fail("getrusage");
|
|
757
764
|
|
|
@@ -957,12 +964,17 @@ void Init_wait3(void)
|
|
|
957
964
|
rb_define_const(rb_mProcess, "P_PROJID", INT2FIX(P_PROJID));
|
|
958
965
|
#endif
|
|
959
966
|
|
|
967
|
+
#ifdef HAVE_CONST_P_JAILID
|
|
968
|
+
/* Process jail ID */
|
|
969
|
+
rb_define_const(rb_mProcess, "P_JAILID", INT2FIX(P_JAILID));
|
|
970
|
+
#endif
|
|
971
|
+
|
|
960
972
|
#ifdef HAVE_CONST_RUSAGE_THREAD
|
|
961
973
|
rb_define_const(rb_mProcess, "RUSAGE_THREAD", INT2FIX(RUSAGE_THREAD));
|
|
962
974
|
#endif
|
|
963
975
|
|
|
964
|
-
/* 1.9.
|
|
965
|
-
rb_define_const(rb_mProcess, "WAIT3_VERSION", rb_str_freeze(rb_str_new2("1.9.
|
|
976
|
+
/* 1.9.3: The version of the proc-wait3 library */
|
|
977
|
+
rb_define_const(rb_mProcess, "WAIT3_VERSION", rb_str_freeze(rb_str_new2("1.9.3")));
|
|
966
978
|
|
|
967
979
|
/* Define this last in our Init_wait3 function */
|
|
968
980
|
rb_define_readonly_variable("$last_status", &v_last_status);
|
data/lib/proc-wait3.rb
CHANGED
data/proc-wait3.gemspec
CHANGED
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |spec|
|
|
4
4
|
spec.name = 'proc-wait3'
|
|
5
|
-
spec.version = '1.9.
|
|
5
|
+
spec.version = '1.9.3'
|
|
6
6
|
spec.author = 'Daniel J. Berger'
|
|
7
7
|
spec.license = 'Apache-2.0'
|
|
8
8
|
spec.email = 'djberg96@gmail.com'
|
|
@@ -10,11 +10,13 @@ Gem::Specification.new do |spec|
|
|
|
10
10
|
spec.summary = 'Adds wait3, wait4 and other methods to the Process module'
|
|
11
11
|
spec.test_file = 'spec/proc_wait3_spec.rb'
|
|
12
12
|
spec.extensions = ['ext/extconf.rb']
|
|
13
|
-
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
|
13
|
+
spec.files = Dir['**/*'].reject { |f| f.include?('git') }
|
|
14
14
|
spec.cert_chain = Dir['certs/*']
|
|
15
15
|
|
|
16
16
|
spec.add_development_dependency('rake')
|
|
17
17
|
spec.add_development_dependency('rspec', '~> 3.9')
|
|
18
|
+
spec.add_development_dependency('rubocop')
|
|
19
|
+
spec.add_development_dependency('rubocop-rspec')
|
|
18
20
|
|
|
19
21
|
spec.metadata = {
|
|
20
22
|
'homepage_uri' => 'https://github.com/djberg96/proc-wait3',
|
|
@@ -23,7 +25,8 @@ Gem::Specification.new do |spec|
|
|
|
23
25
|
'documentation_uri' => 'https://github.com/djberg96/proc-wait3/wiki',
|
|
24
26
|
'source_code_uri' => 'https://github.com/djberg96/proc-wait3',
|
|
25
27
|
'wiki_uri' => 'https://github.com/djberg96/proc-wait3/wiki',
|
|
26
|
-
'rubygems_mfa_required' => 'true'
|
|
28
|
+
'rubygems_mfa_required' => 'true',
|
|
29
|
+
'github_repo' => 'https://github.com/djberg96/proc-wait3'
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
spec.description = <<-EOF
|
data/spec/proc_wait3_spec.rb
CHANGED
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
##############################################################################
|
|
2
4
|
# proc_wait3_spec.rb
|
|
3
5
|
#
|
|
4
|
-
# Test suite for the Ruby proc-wait3 library. You should run these
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
# Test suite for the Ruby proc-wait3 library. You should run these via the
|
|
7
|
+
# 'rake spec' task.
|
|
8
|
+
#
|
|
9
|
+
# Note that several specs are deliberately wrapped in EINTR rescue handlers
|
|
10
|
+
# because I think the Ruby interpreter is sending a signal to the process
|
|
11
|
+
# from somewhere in the guts of its core code. Originally I thought this was
|
|
12
|
+
# a SIGCHLD but it doesn't always appear to be.
|
|
13
|
+
##############################################################################
|
|
14
|
+
require 'English'
|
|
15
|
+
require 'spec_helper'
|
|
9
16
|
require 'rbconfig'
|
|
10
17
|
|
|
11
18
|
RSpec.describe Process do
|
|
12
|
-
# Something in the guts of Ruby was being a pain.
|
|
13
|
-
Signal.trap('CHLD', 'IGNORE') if RUBY_VERSION.to_f < 3
|
|
14
|
-
|
|
15
|
-
let(:solaris) { RbConfig::CONFIG['host_os'] =~ /sunos|solaris/i }
|
|
16
|
-
let(:darwin) { RbConfig::CONFIG['host_os'] =~ /darwin|osx/i }
|
|
17
|
-
let(:hpux) { RbConfig::CONFIG['host_os'] =~ /hpux/i }
|
|
18
|
-
let(:linux) { RbConfig::CONFIG['host_os'] =~ /linux/i }
|
|
19
|
-
let(:bsd) { RbConfig::CONFIG['host_os'] =~ /bsd|dragonfly/i }
|
|
20
|
-
|
|
21
19
|
let(:proc_stat_members) {
|
|
22
20
|
%i[
|
|
23
21
|
pid status utime stime maxrss ixrss idrss isrss minflt majflt nswap
|
|
@@ -31,192 +29,175 @@ RSpec.describe Process do
|
|
|
31
29
|
@pid = nil
|
|
32
30
|
end
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
def call_wait3
|
|
33
|
+
described_class.wait3
|
|
34
|
+
rescue Errno::EINTR
|
|
35
|
+
retry
|
|
37
36
|
end
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
def call_wait4(*args)
|
|
39
|
+
described_class.wait4(*args)
|
|
40
|
+
rescue Errno::EINTR
|
|
41
|
+
retry
|
|
41
42
|
end
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
def call_waitid(*args)
|
|
45
|
+
described_class.waitid(*args)
|
|
46
|
+
rescue Errno::EINTR
|
|
47
|
+
retry
|
|
47
48
|
end
|
|
48
49
|
|
|
49
|
-
example
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
expect{ @proc_stat = Process.wait3 }.not_to raise_error
|
|
53
|
-
expect( @proc_stat.members).to eq(proc_stat_members)
|
|
50
|
+
example 'version constant is set to expected value' do
|
|
51
|
+
expect(Process::WAIT3_VERSION).to eq('1.9.3')
|
|
52
|
+
expect(Process::WAIT3_VERSION).to be_frozen
|
|
54
53
|
end
|
|
55
54
|
|
|
56
|
-
example
|
|
57
|
-
|
|
58
|
-
expect{ Process.wait3(Process::WNOHANG) }.not_to raise_error
|
|
55
|
+
example 'wait3 method is defined' do
|
|
56
|
+
expect(described_class).to respond_to(:wait3)
|
|
59
57
|
end
|
|
60
58
|
|
|
61
|
-
example
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Process.wait3
|
|
65
|
-
expect($last_status).to be_kind_of(Struct::ProcStat)
|
|
66
|
-
expect($last_status).not_to be_nil
|
|
59
|
+
example 'wait3 works as expected' do
|
|
60
|
+
@pid = fork { sleep 0.5 }
|
|
61
|
+
expect { call_wait3 }.not_to raise_error
|
|
67
62
|
end
|
|
68
63
|
|
|
69
|
-
example
|
|
70
|
-
|
|
71
|
-
@
|
|
72
|
-
|
|
73
|
-
expect($?).not_to be_nil
|
|
64
|
+
example 'wait3 returns the expected proc status members' do
|
|
65
|
+
@pid = fork { sleep 0.5 }
|
|
66
|
+
expect { @proc_stat = call_wait3 }.not_to raise_error
|
|
67
|
+
expect(@proc_stat.members).to eq(proc_stat_members)
|
|
74
68
|
end
|
|
75
69
|
|
|
76
|
-
example
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
struct = Process.wait3
|
|
80
|
-
expect(struct).to be_frozen
|
|
70
|
+
example 'wait3 with WNOHANG works as expected' do
|
|
71
|
+
@pid = fork { sleep 0.5 }
|
|
72
|
+
expect { described_class.wait3(Process::WNOHANG) }.not_to raise_error
|
|
81
73
|
end
|
|
82
74
|
|
|
83
|
-
example
|
|
84
|
-
|
|
75
|
+
example 'wait3 sets and returns $last_status to expected values' do
|
|
76
|
+
@pid = fork { sleep 0.5 }
|
|
77
|
+
call_wait3
|
|
78
|
+
expect($last_status).to be_a(Struct::ProcStat)
|
|
79
|
+
expect($last_status).not_to be_nil
|
|
80
|
+
end
|
|
85
81
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
example 'wait3 sets pid and status members of $?' do
|
|
83
|
+
@pid = fork { sleep 0.5 }
|
|
84
|
+
call_wait3
|
|
85
|
+
expect($CHILD_STATUS).not_to be_nil
|
|
89
86
|
end
|
|
90
87
|
|
|
91
|
-
example
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
example 'wait3 returns frozen struct' do
|
|
89
|
+
@pid = fork { sleep 0.5 }
|
|
90
|
+
struct = call_wait3
|
|
91
|
+
expect(struct).to be_frozen
|
|
94
92
|
end
|
|
95
93
|
|
|
96
|
-
example
|
|
97
|
-
|
|
98
|
-
expect
|
|
94
|
+
example 'getdtablesize works as expected', :solaris do
|
|
95
|
+
expect(described_class).to respond_to(:getdtablesize)
|
|
96
|
+
expect(described_class.getdtablesize).to be_a(Integer)
|
|
97
|
+
assert(described_class.getdtablesize > 0)
|
|
99
98
|
end
|
|
100
99
|
|
|
101
|
-
example
|
|
102
|
-
|
|
100
|
+
example 'wait4 method is defined', :skip_hpux do
|
|
101
|
+
expect(described_class).to respond_to(:wait4)
|
|
102
|
+
end
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
expect{
|
|
106
|
-
expect(@proc_stat).to be_kind_of(Struct::ProcStat)
|
|
104
|
+
example 'wait4 requires at least one argument', :skip_hpux do
|
|
105
|
+
expect { call_wait4 }.to raise_error(ArgumentError)
|
|
107
106
|
end
|
|
108
107
|
|
|
109
|
-
example
|
|
110
|
-
|
|
108
|
+
example 'wait4 works as expected', :skip_hpux do
|
|
109
|
+
@pid = fork { sleep 0.5 }
|
|
110
|
+
expect { @proc_stat = call_wait4(@pid) }.not_to raise_error
|
|
111
|
+
expect(@proc_stat).to be_a(Struct::ProcStat)
|
|
112
|
+
end
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
114
|
+
example 'wait4 sets and returns $last_status to expected values', :skip_hpux do
|
|
115
|
+
@pid = fork { sleep 0.5 }
|
|
116
|
+
call_wait4(@pid)
|
|
117
|
+
expect($last_status).to be_a(Struct::ProcStat)
|
|
115
118
|
expect($last_status).not_to be_nil
|
|
116
119
|
end
|
|
117
120
|
|
|
118
|
-
example
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
Process.wait4(@pid)
|
|
123
|
-
expect($?).not_to be_nil
|
|
121
|
+
example 'wait4 sets pid and status members of $?', :skip_hpux do
|
|
122
|
+
@pid = fork { sleep 0.5 }
|
|
123
|
+
call_wait4(@pid)
|
|
124
|
+
expect($CHILD_STATUS).not_to be_nil
|
|
124
125
|
end
|
|
125
126
|
|
|
126
|
-
example
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
@pid = fork{ sleep 0.5 }
|
|
130
|
-
struct = Process.wait4(@pid)
|
|
127
|
+
example 'wait4 returns frozen struct', :skip_hpux do
|
|
128
|
+
@pid = fork { sleep 0.5 }
|
|
129
|
+
struct = call_wait4(@pid)
|
|
131
130
|
expect(struct).to be_frozen
|
|
132
131
|
end
|
|
133
132
|
|
|
134
|
-
example
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
expect(Process).to respond_to(:waitid)
|
|
133
|
+
example 'waitid method is defined', :skip_hpux do
|
|
134
|
+
expect(described_class).to respond_to(:waitid)
|
|
138
135
|
end
|
|
139
136
|
|
|
140
|
-
example
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
@pid = fork{ sleep 0.5 }
|
|
144
|
-
expect{ Process.waitid(Process::P_PID, @pid, Process::WEXITED) }.not_to raise_error
|
|
137
|
+
example 'waitid method works as expected', :skip_hpux do
|
|
138
|
+
@pid = fork { sleep 0.5 }
|
|
139
|
+
expect { call_waitid(Process::P_PID, @pid, Process::WEXITED) }.not_to raise_error
|
|
145
140
|
end
|
|
146
141
|
|
|
147
|
-
example
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
@pid
|
|
151
|
-
expect{ Process
|
|
152
|
-
expect{ Process.waitid(Process::P_PID, @pid, "foo") }.to raise_error(TypeError)
|
|
153
|
-
expect{ Process.waitid(Process::P_PID, "foo", Process::WEXITED) }.to raise_error(TypeError)
|
|
142
|
+
example 'waitid method raises expected errors if wrong argument type is passed', :skip_hpux do
|
|
143
|
+
@pid = fork { sleep 0.5 }
|
|
144
|
+
expect { call_waitid('foo', @pid, Process::WEXITED) }.to raise_error(TypeError)
|
|
145
|
+
expect { call_waitid(Process::P_PID, @pid, 'foo') }.to raise_error(TypeError)
|
|
146
|
+
expect { call_waitid(Process::P_PID, 'foo', Process::WEXITED) }.to raise_error(TypeError)
|
|
154
147
|
end
|
|
155
148
|
|
|
156
|
-
example
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
@pid = fork{ sleep 0.5 }
|
|
160
|
-
expect{ Process.waitid(Process::P_PID, 99999999, Process::WEXITED) }.to raise_error(Errno::ECHILD)
|
|
149
|
+
example 'waitid method raises expected error if invalid argument is passed', :skip_hpux do
|
|
150
|
+
@pid = fork { sleep 0.5 }
|
|
151
|
+
expect { described_class.waitid(Process::P_PID, 99999999, Process::WEXITED) }.to raise_error(Errno::ECHILD)
|
|
161
152
|
end
|
|
162
153
|
|
|
163
|
-
example
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
expect(Process).to respond_to(:sigsend)
|
|
154
|
+
example 'sigsend method is defined', :solaris do
|
|
155
|
+
expect(described_class).to respond_to(:sigsend)
|
|
167
156
|
end
|
|
168
157
|
|
|
169
|
-
example
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
@pid = fork{ sleep 0.5 }
|
|
173
|
-
expect{ Process.sigsend(Process::P_PID, @pid, 0) }.not_to raise_error
|
|
158
|
+
example 'sigsend works as expected', :solaris do
|
|
159
|
+
@pid = fork { sleep 0.5 }
|
|
160
|
+
expect { described_class.sigsend(Process::P_PID, @pid, 0) }.not_to raise_error
|
|
174
161
|
end
|
|
175
162
|
|
|
176
|
-
example
|
|
177
|
-
expect(
|
|
163
|
+
example 'getrusage method is defined' do
|
|
164
|
+
expect(described_class).to respond_to(:getrusage)
|
|
178
165
|
end
|
|
179
166
|
|
|
180
|
-
example
|
|
181
|
-
@pid = fork{ sleep 0.5 }
|
|
167
|
+
example 'getrusage works as expected' do
|
|
168
|
+
@pid = fork { sleep 0.5 }
|
|
182
169
|
|
|
183
|
-
expect{
|
|
184
|
-
expect{
|
|
170
|
+
expect { described_class.getrusage }.not_to raise_error
|
|
171
|
+
expect { described_class.getrusage(true) }.not_to raise_error
|
|
185
172
|
end
|
|
186
173
|
|
|
187
|
-
example
|
|
188
|
-
|
|
189
|
-
expect{ Process.getrusage(Process::RUSAGE_THREAD) }.not_to raise_error
|
|
174
|
+
example 'getrusage can get thread info on Linux', :linux do
|
|
175
|
+
expect { described_class.getrusage(Process::RUSAGE_THREAD) }.not_to raise_error
|
|
190
176
|
end
|
|
191
177
|
|
|
192
|
-
example
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
expect(
|
|
197
|
-
expect(Process.getrusage.stime).to be_kind_of(Float)
|
|
198
|
-
expect(Process.getrusage.utime).to be_kind_of(Float)
|
|
178
|
+
example 'getrusage returns the expected struct', :linux do
|
|
179
|
+
@pid = fork { sleep 0.5 }
|
|
180
|
+
expect(described_class.getrusage).to be_a(Struct::RUsage)
|
|
181
|
+
expect(described_class.getrusage.stime).to be_a(Float)
|
|
182
|
+
expect(described_class.getrusage.utime).to be_a(Float)
|
|
199
183
|
end
|
|
200
184
|
|
|
201
|
-
example
|
|
202
|
-
expect(
|
|
185
|
+
example 'pause method is defined' do
|
|
186
|
+
expect(described_class).to respond_to(:pause)
|
|
203
187
|
end
|
|
204
188
|
|
|
205
|
-
example
|
|
206
|
-
skip 'wait constant check skipped on this platform' if darwin || bsd
|
|
207
|
-
|
|
189
|
+
example 'expected constants are defined', :skip_darwin, :skip_bsd do
|
|
208
190
|
expect(Process::WCONTINUED).not_to be_nil
|
|
209
191
|
expect(Process::WEXITED).not_to be_nil
|
|
210
192
|
expect(Process::WNOWAIT).not_to be_nil
|
|
211
193
|
expect(Process::WSTOPPED).not_to be_nil
|
|
194
|
+
end
|
|
212
195
|
|
|
213
|
-
|
|
196
|
+
example 'expected constant WTRAPPED is defined', :bsd do
|
|
214
197
|
expect(Process::WTRAPPED).not_to be_nil
|
|
215
198
|
end
|
|
216
199
|
|
|
217
|
-
example
|
|
218
|
-
skip 'process type flag check skipped on this platform' if linux || darwin || bsd
|
|
219
|
-
|
|
200
|
+
example 'expected process type flag constants are defined', :solaris do
|
|
220
201
|
expect(Process::P_ALL).not_to be_nil
|
|
221
202
|
expect(Process::P_CID).not_to be_nil
|
|
222
203
|
expect(Process::P_GID).not_to be_nil
|
|
@@ -224,18 +205,18 @@ RSpec.describe Process do
|
|
|
224
205
|
expect(Process::P_PID).not_to be_nil
|
|
225
206
|
expect(Process::P_SID).not_to be_nil
|
|
226
207
|
expect(Process::P_UID).not_to be_nil
|
|
227
|
-
|
|
228
|
-
skip 'P_MYID constant check skipped on this platform' unless solaris
|
|
229
208
|
expect(Process::P_MYID).not_to be_nil
|
|
230
209
|
end
|
|
231
210
|
|
|
232
|
-
example
|
|
233
|
-
skip 'P_TASKID and P_PROJID constant check skipped on this platform' unless solaris
|
|
234
|
-
|
|
211
|
+
example 'solaris-specific process type flags are defined on solaris', :solaris do
|
|
235
212
|
expect(Process::P_TASKID).not_to be_nil
|
|
236
213
|
expect(Process::P_PROJID).not_to be_nil
|
|
237
214
|
end
|
|
238
215
|
|
|
216
|
+
example 'bsd-specific process type flags are defined on BSD platforms', :bsd do
|
|
217
|
+
expect(Process::P_JAILID).not_to be_nil
|
|
218
|
+
end
|
|
219
|
+
|
|
239
220
|
def after
|
|
240
221
|
Process.kill(9, @pid) if @pid
|
|
241
222
|
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rspec'
|
|
4
|
+
require 'proc-wait3'
|
|
5
|
+
|
|
6
|
+
RSpec.configure do |config|
|
|
7
|
+
config.filter_run_excluding(:darwin) if Gem::Platform.local.os !~ /darwin|macos/i
|
|
8
|
+
config.filter_run_excluding(:solaris) if Gem::Platform.local.os !~ /sunos|solaris/i
|
|
9
|
+
config.filter_run_excluding(:bsd) if Gem::Platform.local.os !~ /bsd|dragonfly/i
|
|
10
|
+
config.filter_run_excluding(:linux) if Gem::Platform.local.os !~ /linux/i
|
|
11
|
+
|
|
12
|
+
config.filter_run_excluding(:skip_hpux) if Gem::Platform.local.os =~ /hpux/i
|
|
13
|
+
config.filter_run_excluding(:skip_darwin) if Gem::Platform.local.os =~ /darwin|macos/i
|
|
14
|
+
config.filter_run_excluding(:skip_bsd) if Gem::Platform.local.os =~ /bsd|dragonfly/i
|
|
15
|
+
config.filter_run_excluding(:skip_linux) if Gem::Platform.local.os =~ /linux/i
|
|
16
|
+
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: proc-wait3
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel J. Berger
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain:
|
|
11
11
|
- |
|
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
|
35
35
|
ORVCZpRuCPpmC8qmqxUnARDArzucjaclkxjLWvCVHeFa9UP7K3Nl9oTjJNv+7/jM
|
|
36
36
|
WZs4eecIcUc4tKdHxcAJ0MO/Dkqq7hGaiHpwKY76wQ1+8xAh
|
|
37
37
|
-----END CERTIFICATE-----
|
|
38
|
-
date: 2024-
|
|
38
|
+
date: 2024-05-04 00:00:00.000000000 Z
|
|
39
39
|
dependencies:
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: rake
|
|
@@ -65,6 +65,34 @@ dependencies:
|
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
67
|
version: '3.9'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: rubocop
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rubocop-rspec
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
68
96
|
description: |2
|
|
69
97
|
The proc-wait3 library adds the wait3, wait4, waitid, pause, sigsend,
|
|
70
98
|
and getrusage methods to the Process module.
|
|
@@ -92,6 +120,7 @@ files:
|
|
|
92
120
|
- lib/proc-wait3.rb
|
|
93
121
|
- proc-wait3.gemspec
|
|
94
122
|
- spec/proc_wait3_spec.rb
|
|
123
|
+
- spec/spec_helper.rb
|
|
95
124
|
homepage: https://github.com/djberg96/proc-wait3
|
|
96
125
|
licenses:
|
|
97
126
|
- Apache-2.0
|
|
@@ -103,7 +132,8 @@ metadata:
|
|
|
103
132
|
source_code_uri: https://github.com/djberg96/proc-wait3
|
|
104
133
|
wiki_uri: https://github.com/djberg96/proc-wait3/wiki
|
|
105
134
|
rubygems_mfa_required: 'true'
|
|
106
|
-
|
|
135
|
+
github_repo: https://github.com/djberg96/proc-wait3
|
|
136
|
+
post_install_message:
|
|
107
137
|
rdoc_options: []
|
|
108
138
|
require_paths:
|
|
109
139
|
- lib
|
|
@@ -118,8 +148,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
118
148
|
- !ruby/object:Gem::Version
|
|
119
149
|
version: '0'
|
|
120
150
|
requirements: []
|
|
121
|
-
rubygems_version: 3.
|
|
122
|
-
signing_key:
|
|
151
|
+
rubygems_version: 3.4.19
|
|
152
|
+
signing_key:
|
|
123
153
|
specification_version: 4
|
|
124
154
|
summary: Adds wait3, wait4 and other methods to the Process module
|
|
125
155
|
test_files:
|
metadata.gz.sig
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
�bj<d������&qN�
|
|
2
|
+
�溨}gdԥwf*����J�˚䋓t��!FI��`<�ѝ��Gd9ʦ��<� ���`��,{R�����y�R��#9w̻�2zk� T�'@��h�װh��S� �q��_�����v� jљ�J��Y�g2��~C(�>ҵpMNn�f��I��T��dE�פ�SCPn�2h��(�X$��|Rb�n6�9��O��Oȉ^�'
|
|
3
|
+
p���pN���"��n-�M~е:Jc��U��lQ�c���D�z�˾����p�� "$Gu'��w'�[47����q�E�c/�JCh������$��~/��E"[7����R��β�3������Iˍ���9�s�vG��.��8�ZX�ô�B�
|